/* ARM assembly Raspberry PI  */
/*  program xpathXml.s   */

/* Constantes    */
.equ STDOUT, 1     @ Linux output console
.equ EXIT,   1     @ Linux syscall
.equ WRITE,  4     @ Linux syscall

.equ NBMAXELEMENTS,    100

/*******************************************/
/* Structures                               */
/********************************************/
/* structure xmlNode*/
    .struct  0
xmlNode_private:                         @ application data
    .struct  xmlNode_private + 4
xmlNode_type:                            @ type number, must be second !
    .struct  xmlNode_type + 4
xmlNode_name:                            @ the name of the node, or the entity
    .struct  xmlNode_name + 4
xmlNode_children:                        @ parent->childs link
    .struct  xmlNode_children + 4
xmlNode_last:                            @ last child link
    .struct  xmlNode_last + 4
xmlNode_parent:                          @ child->parent link
    .struct  xmlNode_parent + 4
xmlNode_next:                            @ next sibling link
    .struct  xmlNode_next + 4
xmlNode_prev:                            @ previous sibling link
    .struct  xmlNode_prev + 4
xmlNode_doc:                             @ the containing document
    .struct  xmlNode_doc + 4
xmlNode_ns:                              @ pointer to the associated namespace
    .struct  xmlNode_ns + 4
xmlNode_content:                         @ the content
    .struct  xmlNode_content + 4
xmlNode_properties:                      @ properties list
    .struct  xmlNode_properties + 4
xmlNode_nsDef:                           @ namespace definitions on this node
    .struct  xmlNode_nsDef + 4
xmlNode_psvi:                            @ for type/PSVI informations
    .struct  xmlNode_psvi + 4
xmlNode_line:                            @ line number
    .struct  xmlNode_line + 4
xmlNode_extra:                           @ extra data for XPath/XSLT
    .struct  xmlNode_extra + 4
xmlNode_fin:
/********************************************/
/* structure xmlNodeSet*/
    .struct  0
xmlNodeSet_nodeNr:                       @ number of nodes in the set
    .struct  xmlNodeSet_nodeNr + 4
xmlNodeSet_nodeMax:                      @ size of the array as allocated
    .struct  xmlNodeSet_nodeMax + 4
xmlNodeSet_nodeTab:                      @ array of nodes in no particular order
    .struct  xmlNodeSet_nodeTab + 4
xmlNodeSet_fin:
/********************************************/
/* structure xmlXPathObject*/
    .struct  0
xmlPathObj_type:                         @
    .struct  xmlPathObj_type + 4
xmlPathObj_nodesetval:                   @
    .struct  xmlPathObj_nodesetval + 4
xmlPathObj_boolval:                      @
    .struct  xmlPathObj_boolval + 4
xmlPathObj_floatval:                     @
    .struct  xmlPathObj_floatval + 4
xmlPathObj_stringval:                    @
    .struct  xmlPathObj_stringval + 4
xmlPathObj_user:                         @
    .struct  xmlPathObj_user + 4
xmlPathObj_index:                        @
    .struct  xmlPathObj_index + 4
xmlPathObj_user2:                        @
    .struct  xmlPathObj_user2 + 4
xmlPathObj_index2:                       @
    .struct  xmlPathObj_index2 + 4

/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessEndpgm:      .asciz "\nNormal end of program.\n"
szMessDisVal:      .asciz "\nDisplay set values.\n"
szMessDisArea:     .asciz "\nDisplay area values.\n"
szFileName:        .asciz "testXml.xml"
szMessError:       .asciz "Error detected !!!!. \n"

szLibName:         .asciz "name"
szLibPrice:        .asciz "//price"
szLibExtName:      .asciz "//name"
szCarriageReturn:  .asciz "\n"

/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
.align 4
tbExtract:          .skip 4 * NBMAXELEMENTS      @ result extract area
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                                     @ entry of program
    ldr r0,iAdrszFileName
    bl xmlParseFile                       @ create doc
    mov r9,r0                             @ doc address
    mov r0,r9                             @ doc
    bl xmlDocGetRootElement               @ get root
    bl xmlFirstElementChild               @ get first section
    bl xmlFirstElementChild               @ get first item
    bl xmlFirstElementChild               @ get first name
    bl xmlNodeGetContent                  @ extract content
    bl affichageMess                      @ for display
    ldr r0,iAdrszCarriageReturn
    bl affichageMess

    ldr r0,iAdrszMessDisVal
    bl affichageMess
    mov r0,r9
    ldr r1,iAdrszLibPrice                  @ extract prices
    bl extractValue
    mov r0,r9
    ldr r1,iAdrszLibExtName                @ extact names
    bl extractValue
    ldr r0,iAdrszMessDisArea
    bl affichageMess
    mov r4,#0                              @ display string result area
    ldr r5,iAdrtbExtract
1:
    ldr r0,[r5,r4,lsl #2]
    cmp r0,#0
    beq 2f
    bl affichageMess
    ldr r0,iAdrszCarriageReturn
    bl affichageMess
    add r4,#1
    b 1b

2:
    mov r0,r9
    bl xmlFreeDoc
    bl xmlCleanupParser
    ldr r0,iAdrszMessEndpgm
    bl affichageMess
    b 100f
99:
    @ error
    ldr r0,iAdrszMessError
    bl affichageMess
100:                                       @ standard end of the program
    mov r0, #0                             @ return code
    mov r7, #EXIT                          @ request to exit program
    svc #0                                 @ perform the system call

iAdrszMessError:          .int szMessError
iAdrszMessEndpgm:         .int szMessEndpgm
iAdrszLibName:            .int szLibName
iAdrszLibPrice:           .int szLibPrice
iAdrszCarriageReturn:     .int szCarriageReturn
iAdrszFileName:           .int szFileName
iAdrszLibExtName:         .int szLibExtName
iAdrtbExtract:            .int tbExtract
iAdrszMessDisVal:          .int szMessDisVal
iAdrszMessDisArea:         .int szMessDisArea
/******************************************************************/
/*     extract value of set                                       */
/******************************************************************/
/* r0 contains the doc address
/* r1 contains the address of the libel to extract */
extractValue:
    push {r1-r10,lr}                     @ save  registres
    mov r4,r1                            @ save address libel
    mov r9,r0                            @ save doc
    ldr r8,iAdrtbExtract
    bl xmlXPathNewContext                @ create context
    mov r10,r0
    mov r1,r0
    mov r0,r4
    bl xmlXPathEvalExpression
    mov r5,r0
    mov r0,r10
    bl xmlXPathFreeContext               @ free context
    cmp r5,#0
    beq 100f
    ldr r4,[r5,#xmlPathObj_nodesetval]   @ values set
    ldr r6,[r4,#xmlNodeSet_nodeNr]       @ set size
    mov r7,#0                            @ index
    ldr r4,[r4,#xmlNodeSet_nodeTab]      @ area of nods
1:                                       @ start loop
    ldr r3,[r4,r7,lsl #2]                @ load node
    mov r0,r9
    ldr r1,[r3,#xmlNode_children]        @ load string value
    mov r2,#1
    bl xmlNodeListGetString
    str r0,[r8,r7,lsl #2]                @ store string pointer in area
    bl affichageMess                     @ and display string result
    ldr r0,iAdrszCarriageReturn
    bl affichageMess
    add r7,#1
    cmp r7,r6
    blt 1b
100:
    pop {r1-r10,lr}                      @ restaur registers */
    bx lr                                @ return

/******************************************************************/
/*     display text with size calculation                         */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
    push {r0,r1,r2,r7,lr}                   @ save  registres
    mov r2,#0                               @ counter length
1:                                          @ loop length calculation
    ldrb r1,[r0,r2]                         @ read octet start position + index
    cmp r1,#0                               @ if 0 its over
    addne r2,r2,#1                          @ else add 1 in the length
    bne 1b                                  @ and loop
                                            @ so here r2 contains the length of the message
    mov r1,r0                               @ address message in r1
    mov r0,#STDOUT                          @ code to write to the standard output Linux
    mov r7, #WRITE                          @ code call system "write"
    svc #0                                  @ call systeme
    pop {r0,r1,r2,r7,lr}                    @ restaur registers */
    bx lr                                   @ return


FileRead, inventory, xmlfile.xml

RegExMatch(inventory, "<item.*?</item>", item1)
MsgBox % item1

pos = 1
While, pos := RegExMatch(inventory, "<price>(.*?)</price>", price, pos + 1)
  MsgBox % price1

While, pos := RegExMatch(inventory, "<name>.*?</name>", name, pos + 1)
  names .= name . "`n"
MsgBox % names


{Retrieve the first "item" element}
(   nestML$(get$("doc.xml",X,ML))
  :   ?
      ( inventory
      . ?,? (section.?,? ((item.?):?item) ?) ?
      )
      ?
& out$(toML$!item)
)

{Perform an action on each "price" element (print it out)}
(   nestML$(get$("doc.xml",X,ML))
  :   ?
      ( inventory
      .   ?
        ,   ?
            ( section
            .   ?
              ,   ?
                  ( item
                  .   ?
                    ,   ?
                        ( price
                        .   ?
                          ,   ?price
                            & out$!price
                            & ~
                        )
                        ?
                  )
                  ?
            )
            ?
      )
      ?
|
)

{Get an array of all the "name" elements}
(   :?anArray
  &   nestML$(get$("doc.xml",X,ML))
    :   ?
        ( inventory
        .   ?
          ,   ?
              ( section
              .   ?
                ,   ?
                    ( item
                    .   ?
                      ,   ?
                          ( name
                          .   ?
                            ,   ?name
                              & !anArray !name:?anArray
                              & ~
                          )
                          ?
                    )
                    ?
              )
              ?
        )
        ?
| out$!anArray {Not truly an array, but a list.}
);


#include <libxml/parser.h>
#include <libxml/xpath.h>

xmlDocPtr getdoc (char *docname) {
	xmlDocPtr doc;
	doc = xmlParseFile(docname);

	return doc;
}

xmlXPathObjectPtr getnodeset (xmlDocPtr doc, xmlChar *xpath){

	xmlXPathContextPtr context;
	xmlXPathObjectPtr result;

	context = xmlXPathNewContext(doc);

	result = xmlXPathEvalExpression(xpath, context);
	xmlXPathFreeContext(context);

	return result;
}

int main(int argc, char **argv) {

	if (argc <= 2) {
		printf("Usage: %s <XML Document Name> <XPath expression>\n", argv[0]);
		return 0;
	}

	char *docname;
	xmlDocPtr doc;
	xmlChar *xpath = (xmlChar*) argv[2];
	xmlNodeSetPtr nodeset;
	xmlXPathObjectPtr result;
	int i;
	xmlChar *keyword;

	docname = argv[1];
	doc = getdoc(docname);
	result = getnodeset (doc, xpath);
	if (result) {
		nodeset = result->nodesetval;
		for (i=0; i < nodeset->nodeNr; i++) {
		xmlNodePtr titleNode = nodeset->nodeTab[i];
		keyword = xmlNodeListGetString(doc, titleNode->xmlChildrenNode, 1);
		printf("Value %d: %s\n",i+1, keyword);
		xmlFree(keyword);
		}
		xmlXPathFreeObject (result);
	}
	xmlFreeDoc(doc);
	xmlCleanupParser();
	return 0;
}


XmlReader XReader;

// Either read the xml from a string ...
XReader = XmlReader.Create(new StringReader("<inventory title=... </inventory>"));

// ... or read it from the file system.
XReader = XmlReader.Create("xmlfile.xml");

// Create a XPathDocument object (which implements the IXPathNavigable interface)
// which is optimized for XPath operation. (very fast).
IXPathNavigable XDocument = new XPathDocument(XReader);

// Create a Navigator to navigate through the document.
XPathNavigator Nav = XDocument.CreateNavigator();
Nav = Nav.SelectSingleNode("//item");

// Move to the first element of the selection. (if available).
if(Nav.MoveToFirst())
{
  Console.WriteLine(Nav.OuterXml); // The outer xml of the first item element.
}

// Get an iterator to loop over multiple selected nodes.
XPathNodeIterator Iterator = XDocument.CreateNavigator().Select("//price");

while (Iterator.MoveNext())
{
  Console.WriteLine(Iterator.Current.Value);
}

Iterator = XDocument.CreateNavigator().Select("//name");

// Use a generic list.
List<string> NodesValues = new List<string>();

while (Iterator.MoveNext())
{
  NodesValues.Add(Iterator.Current.Value);
}

// Convert the generic list to an array and output the count of items.
Console.WriteLine(NodesValues.ToArray().Length);


#include <cassert>
#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <utility>
#include <vector>

#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlerror.h>
#include <libxml/xmlstring.h>
#include <libxml/xmlversion.h>
#include <libxml/xpath.h>

#ifndef LIBXML_XPATH_ENABLED
#   error libxml was not configured with XPath support
#endif

// Because libxml2 is a C library, we need a couple things to make it work
// well with modern C++:
//   1) a ScopeGuard-like type to handle cleanup functions; and
//   2) an exception type that transforms the library's errors.

// ScopeGuard-like type to handle C library cleanup functions.
template <typename F>
class [[nodiscard]] scope_exit
{
public:
    // C++20: Constructor can (and should) be [[nodiscard]].
    /*[[nodiscard]]*/ constexpr explicit scope_exit(F&& f) :
        f_{std::move(f)}
    {}

    ~scope_exit()
    {
        f_();
    }

    // Non-copyable, non-movable.
    scope_exit(scope_exit const&) = delete;
    scope_exit(scope_exit&&) = delete;
    auto operator=(scope_exit const&) -> scope_exit& = delete;
    auto operator=(scope_exit&&) -> scope_exit& = delete;

private:
    F f_;
};

// Exception that gets last libxml2 error.
class libxml_error : public std::runtime_error
{
public:
    libxml_error() : libxml_error(std::string{}) {}

    explicit libxml_error(std::string message) :
        std::runtime_error{make_message_(std::move(message))}
    {}

private:
    static auto make_message_(std::string message) -> std::string
    {
        if (auto const last_error = ::xmlGetLastError(); last_error)
        {
            if (not message.empty())
                message += ": ";
            message += last_error->message;
        }

        return message;
    }
};

auto main() -> int
{
    try
    {
        // Initialize libxml.
        ::xmlInitParser();
        LIBXML_TEST_VERSION
        auto const libxml_cleanup = scope_exit{[] { ::xmlCleanupParser(); }};

        // Load and parse XML document.
        auto const doc = ::xmlParseFile("test.xml");
        if (not doc)
            throw libxml_error{"failed to load document"};
        auto const doc_cleanup = scope_exit{[doc] { ::xmlFreeDoc(doc); }};

        // Create XPath context for document.
        auto const xpath_context = ::xmlXPathNewContext(doc);
        if (not xpath_context)
            throw libxml_error{"failed to create XPath context"};
        auto const xpath_context_cleanup = scope_exit{[xpath_context]
            { ::xmlXPathFreeContext(xpath_context); }};

        // Task 1 ============================================================
        {
            std::cout << "Task 1:\n";

            auto const xpath =
                reinterpret_cast<::xmlChar const*>(u8"//item[1]");

            // Create XPath object (same for every task).
            auto xpath_obj = ::xmlXPathEvalExpression(xpath, xpath_context);
            if (not xpath_obj)
                throw libxml_error{"failed to evaluate XPath"};
            auto const xpath_obj_cleanup = scope_exit{[xpath_obj]
                { ::xmlXPathFreeObject(xpath_obj); }};

            // 'result' a xmlNode* to the desired node, or nullptr if it
            // doesn't exist. If not nullptr, the node is owned by 'doc'.
            auto const result = xmlXPathNodeSetItem(xpath_obj->nodesetval, 0);
            if (result)
                std::cout << '\t' << "node found" << '\n';
            else
                std::cout << '\t' << "node not found" << '\n';
        }

        // Task 2 ============================================================
        {
            std::cout << "Task 2:\n";

            auto const xpath =
                reinterpret_cast<::xmlChar const*>(u8"//price/text()");

            // Create XPath object (same for every task).
            auto xpath_obj = ::xmlXPathEvalExpression(xpath, xpath_context);
            if (not xpath_obj)
                throw libxml_error{"failed to evaluate XPath"};
            auto const xpath_obj_cleanup = scope_exit{[xpath_obj]
                { ::xmlXPathFreeObject(xpath_obj); }};

            // Printing the results.
            auto const count =
                xmlXPathNodeSetGetLength(xpath_obj->nodesetval);
            for (auto i = decltype(count){0}; i < count; ++i)
            {
                auto const node =
                    xmlXPathNodeSetItem(xpath_obj->nodesetval, i);
                assert(node);

                auto const content = XML_GET_CONTENT(node);
                assert(content);

                // Note that reinterpret_cast here is a Bad Idea, because
                // 'content' is UTF-8 encoded, which may or may not be the
                // encoding cout expects. A *PROPER* solution would translate
                // content to the correct encoding (or at least verify that
                // UTF-8 *is* the correct encoding).
                //
                // But this "works" well enough for illustration.
                std::cout << "\n\t" << reinterpret_cast<char const*>(content);
            }

            std::cout << '\n';
        }

        // Task 3 ============================================================
        {
            std::cout << "Task 3:\n";

            auto const xpath =
                reinterpret_cast<::xmlChar const*>(u8"//name");

            // Create XPath object (same for every task).
            auto xpath_obj = ::xmlXPathEvalExpression(xpath, xpath_context);
            if (not xpath_obj)
                throw libxml_error{"failed to evaluate XPath"};
            auto const xpath_obj_cleanup = scope_exit{[xpath_obj]
                { ::xmlXPathFreeObject(xpath_obj); }};

            // 'results' is a vector of pointers to the result nodes. The
            // nodes pointed to are owned by 'doc'.
            auto const results = [ns=xpath_obj->nodesetval]()
            {
                auto v = std::vector<::xmlNode*>{};
                if (ns && ns->nodeTab)
                    v.assign(ns->nodeTab, ns->nodeTab + ns->nodeNr);
                return v;
            }();
            std::cout << '\t' << "set of " << results.size()
                << " node(s) found" << '\n';
        }
    }
    catch (std::exception const& x)
    {
        std::cerr << "ERROR: " << x.what() << '\n';
        return EXIT_FAILURE;
    }
}


Class XML.Inventory [ Abstract ]
{

XData XMLData
{
<inventory title="OmniCorp Store #45x10^3">

    <item upc="123456789" stock="12">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>
    <item upc="445322344" stock="18">
      <name>Levitation Salve</name>
      <price>23.99</price>
      <description>Levitate yourself for up to 3 hours per application</description>
    </item>

    <item upc="485672034" stock="653">
      <name>Blork and Freen Instameal</name>
      <price>4.95</price>
      <description>A tasty meal in a tablet; just add water</description>
    </item>
    <item upc="132957764" stock="44">
      <name>Grob winglets</name>
      <price>3.56</price>
      <description>Tender winglets of Grob. Just add water</description>
    </item>

</inventory>
}

ClassMethod QueryXMLDoc(Output names As %List) As %Status
{
   // get xml stream from the 'XData' block contained in this class
   Set xdata=##class(%Dictionary.CompiledXData).%OpenId($this_"||XMLData",, .sc)
   If $$$ISERR(sc) Quit sc
   Set sc=##class(%XML.XPATH.Document).CreateFromStream(xdata.Data, .xdoc)
   If $$$ISERR(sc) Quit sc

   // retrieve the first 'item' element
   Set sc=xdoc.EvaluateExpression("//section[1]", "item[1]", .res)

   // perform an action on each 'price' element (print it out)
   Set sc=xdoc.EvaluateExpression("//price", "text()", .res)
   If $$$ISERR(sc) Quit sc
   For i=1:1:res.Count() {
	   If i>1 Write ", "
	   Write res.GetAt(i).Value
   }

   // get an array of all the 'name' elements
   Set sc=xdoc.EvaluateExpression("//item", "name", .res)
   If $$$ISERR(sc) Quit sc
   Set key=""
   Do {
	   Set dom=res.GetNext(.key)
	   If '$IsObject(dom) Quit
	   While dom.Read() {
		   If dom.HasValue Set $List(names, key)=dom.Value
	   }
   } While key'=""

   // finished
   Quit $$$OK
}

}


# Retrieve the first "item" element
doc.evaluate('//item', doc, {}, 7, {}).snapshotItem 0

# Perform an action on each "price" element (print it out)
prices = doc.evaluate "//price", doc, {}, 7, {}
for i in [0...prices.snapshotLength] by 1
    console.log prices.snapshotItem(i).textContent

# Get an array of all the "name" elements
names = doc.evaluate "//name", doc, {}, 7, {}
names = for i in [0...names.snapshotLength] by 1
    names.snapshotItem i


<cfsavecontent variable="xmlString">
<inventory
...
</inventory>
</cfsavecontent>
<cfset xml = xmlParse(xmlString)>
<!--- First Task --->
<cfset itemSearch = xmlSearch(xml, "//item")>
<!--- item = the first Item (xml element object) --->
<cfset item = itemSearch[1]>
<!--- Second Task --->
<cfset priceSearch = xmlSearch(xml, "//price")>
<!--- loop and print each price --->
<cfloop from="1" to="#arrayLen(priceSearch)#" index="i">
  #priceSearch[i].xmlText#<br/>
</cfloop>
<!--- Third Task --->
<!--- array of all the name elements --->
<cfset names = xmlSearch(xml, "//name")>
<!--- visualize the results --->
<cfdump var="#variables#">


(dolist (system '(:xpath :cxml-stp :cxml))
  (asdf:oos 'asdf:load-op system))

(defparameter *doc* (cxml:parse-file "xml" (stp:make-builder)))

(xpath:first-node (xpath:evaluate "/inventory/section[1]/item[1]" *doc*))

(xpath:do-node-set (node (xpath:evaluate "/inventory/section/item/price/text()" *doc*))
  (format t "~A~%" (stp:data node)))

(defun node-array (node-set)
  (coerce (xpath:all-nodes node-set) 'vector))

(node-array
 (xpath:evaluate "/inventory/section/item/name" *doc*))


import kxml.xml;
char[]xmlinput =
"<inventory title=\"OmniCorp Store #45x10^3\">

    <item upc=\"123456789\" stock=\"12\">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>
    <item upc=\"445322344\" stock=\"18\">
      <name>Levitation Salve</name>
      <price>23.99</price>
      <description>Levitate yourself for up to 3 hours per application</description>
    </item>

    <item upc=\"485672034\" stock=\"653\">
      <name>Blork and Freen Instameal</name>
      <price>4.95</price>
      <description>A tasty meal in a tablet; just add water</description>
    </item>
    <item upc=\"132957764\" stock=\"44\">
      <name>Grob winglets</name>
      <price>3.56</price>
      <description>Tender winglets of Grob. Just add water</description>
    </item>

</inventory>
";
void main() {
        auto root = readDocument(xmlinput);
        auto firstitem = root.parseXPath("inventory/section/item")[0];
        foreach(price;root.parseXPath("inventory/section/item/price")) {
                std.stdio.writefln("%s",price.getCData);
        }
        auto namearray = root.parseXPath("inventory/section/item/name");
}


program XMLXPath;

{$APPTYPE CONSOLE}

uses ActiveX, MSXML;

const
  XML =
    '<inventory title="OmniCorp Store #45x10^3">' +
    '
' +
    '    <item upc="123456789" stock="12">' +
    '      <name>Invisibility Cream</name>' +
    '      <price>14.50</price>' +
    '      <description>Makes you invisible</description>' +
    '    </item>' +
    '    <item upc="445322344" stock="18">' +
    '      <name>Levitation Salve</name>' +
    '      <price>23.99</price>' +
    '      <description>Levitate yourself for up to 3 hours per application</description>' +
    '    </item>' +
    '
' +
    '
' +
    '    <item upc="485672034" stock="653">' +
    '      <name>Blork and Freen Instameal</name>' +
    '      <price>4.95</price>' +
    '      <description>A tasty meal in a tablet; just add water</description>' +
    '    </item>' +
    '    <item upc="132957764" stock="44">' +
    '      <name>Grob winglets</name>' +
    '      <price>3.56</price>' +
    '      <description>Tender winglets of Grob. Just add water</description>' +
    '    </item>' +
    '
' +
    '</inventory>';

var
  i: Integer;
  s: string;
  lXMLDoc: IXMLDOMDocument2;
  lNodeList: IXMLDOMNodeList;
  lNode: IXMLDOMNode;
  lItemNames: array of string;
begin
  CoInitialize(nil);
  lXMLDoc := CoDOMDocument.Create;
  lXMLDoc.setProperty('SelectionLanguage', 'XPath');
  lXMLDoc.loadXML(XML);

  Writeln('First item node:');
  lNode := lXMLDoc.selectNodes('//item')[0];
  Writeln(lNode.xml);
  Writeln('');

  lNodeList := lXMLDoc.selectNodes('//price');
  for i := 0 to lNodeList.length - 1 do
    Writeln('Price = ' + lNodeList[i].text);
  Writeln('');

  lNodeList := lXMLDoc.selectNodes('//item/name');
  SetLength(lItemNames, lNodeList.length);
  for i := 0 to lNodeList.length - 1 do
    lItemNames[i] := lNodeList[i].text;
  for s in lItemNames do
    Writeln('Item name = ' + s);
end.


? def xml__quasiParser := <import:org.switchb.e.xml.makeXMLQuasiParser>()
> def xpath__quasiParser := xml__quasiParser.xPathQuasiParser()
> null

? def doc := xml`<inventory title="OmniCorp Store #45x10^3">
>

>     <item upc="123456789" stock="12">
>       <name>Invisibility Cream</name>
>       <price>14.50</price>
>       <description>Makes you invisible</description>
>     </item>
>     <item upc="445322344" stock="18">
>       <name>Levitation Salve</name>
>       <price>23.99</price>
>       <description>Levitate yourself for up to 3 hours per application</description>n>
>     </item>
>

>

>     <item upc="485672034" stock="653">
>       <name>Blork and Freen Instameal</name>
>       <price>4.95</price>
>       <description>A tasty meal in a tablet; just add water</description>
>     </item>
>     <item upc="132957764" stock="44">
>       <name>Grob winglets</name>
>       <price>3.56</price>
>       <description>Tender winglets of Grob. Just add water</description>
>     </item>
>

> </inventory>`
# value: xml`...`

? doc[xpath`inventory/section/item`][0]
# value: xml`<item stock="12" upc="123456789">
#              <name>Invisibility Cream</name>
#              <price>14.50</price>
#              <description>Makes you invisible</description>
#            </item>`

? for price in doc[xpath`inventory/section/item/price/text()`] { println(price :String) }
14.50
23.99
4.95
3.56

? doc[xpath`inventory/section/item/name`]
# value: [xml`<name>Invisibility Cream</name>`,
#         xml`<name>Levitation Salve</name>`,
#         xml`<name>Blork and Freen Instameal</name>`,
#         xml`<name>Grob winglets</name>`]


-module(xml_xpath).
-include_lib("xmerl/include/xmerl.hrl").

-export([main/0]).

main() ->
   XMLDocument =
      "<inventory title=\"OmniCorp Store #45x10^3\">

          <item upc=\"123456789\" stock=\"12\">
            <name>Invisibility Cream</name>
            <price>14.50</price>
            <description>Makes you invisible</description>
          </item>
          <item upc=\"445322344\" stock=\"18\">
            <name>Levitation Salve</name>
            <price>23.99</price>
            <description>Levitate yourself for up to 3 hours per application</description>
          </item>

          <item upc=\"485672034\" stock=\"653\">
            <name>Blork and Freen Instameal</name>
            <price>4.95</price>
            <description>A tasty meal in a tablet; just add water</description>
          </item>
          <item upc=\"132957764\" stock=\"44\">
            <name>Grob winglets</name>
            <price>3.56</price>
            <description>Tender winglets of Grob. Just add water</description>
          </item>

      </inventory>",
   {Document,_} = xmerl_scan:string(XMLDocument),

   io:format("First item:\n~s\n",
      [lists:flatten(
         xmerl:export_simple(
            [hd(xmerl_xpath:string("//item[1]", Document))],
            xmerl_xml, [{prolog, ""}]))]),

   io:format("Prices:\n"),
   [ io:format("~s\n",[Content#xmlText.value])
      || #xmlElement{content = [Content|_]} <- xmerl_xpath:string("//price", Document)],

   io:format("Names:\n"),
   [ Content#xmlText.value
      || #xmlElement{content = [Content|_]} <- xmerl_xpath:string("//name", Document)].


open System.IO
open System.Xml.XPath

let xml = new StringReader("""
<inventory title="OmniCorp Store #45x10^3">

    <item upc="123456789" stock="12">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>
    <item upc="445322344" stock="18">
      <name>Levitation Salve</name>
      <price>23.99</price>
      <description>Levitate yourself for up to 3 hours per application</description>
    </item>

    <item upc="485672034" stock="653">
      <name>Blork and Freen Instameal</name>
      <price>4.95</price>
      <description>A tasty meal in a tablet; just add water</description>
    </item>
    <item upc="132957764" stock="44">
      <name>Grob winglets</name>
      <price>3.56</price>
      <description>Tender winglets of Grob. Just add water</description>
    </item>

</inventory>
""")

let nav = XPathDocument(xml).CreateNavigator()

// first "item"; throws if none exists
let item = nav.SelectSingleNode(@"//item[1]")

// apply a operation (print text value) to all price elements
for price in nav.Select(@"//price") do
    printfn "%s" (price.ToString())

// array of all name elements
let names = seq { for name in nav.Select(@"//name") do yield name } |> Seq.toArray


! Get first item element
"""<inventory title="OmniCorp Store #45x10^3">

    <item upc="123456789" stock="12">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>
    <item upc="445322344" stock="18">
      <name>Levitation Salve</name>
      <price>23.99</price>
      <description>Levitate yourself for up to 3 hours per application</description>
    </item>

    <item upc="485672034" stock="653">
      <name>Blork and Freen Instameal</name>
      <price>4.95</price>
      <description>A tasty meal in a tablet; just add water</description>
    </item>
    <item upc="132957764" stock="44">
      <name>Grob winglets</name>
      <price>3.56</price>
      <description>Tender winglets of Grob. Just add water</description>
    </item>

</inventory>""" string>xml "item" deep-tag-named

! Print out prices
"""<inventory title="OmniCorp Store #45x10^3">

    <item upc="123456789" stock="12">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>
    <item upc="445322344" stock="18">
      <name>Levitation Salve</name>
      <price>23.99</price>
      <description>Levitate yourself for up to 3 hours per application</description>
    </item>

    <item upc="485672034" stock="653">
      <name>Blork and Freen Instameal</name>
      <price>4.95</price>
      <description>A tasty meal in a tablet; just add water</description>
    </item>
    <item upc="132957764" stock="44">
      <name>Grob winglets</name>
      <price>3.56</price>
      <description>Tender winglets of Grob. Just add water</description>
    </item>

</inventory>""" string>xml "price" deep-tags-named [ children>> first ] map

! Array of all name elements
"""<inventory title="OmniCorp Store #45x10^3">

    <item upc="123456789" stock="12">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>
    <item upc="445322344" stock="18">
      <name>Levitation Salve</name>
      <price>23.99</price>
      <description>Levitate yourself for up to 3 hours per application</description>
    </item>

    <item upc="485672034" stock="653">
      <name>Blork and Freen Instameal</name>
      <price>4.95</price>
      <description>A tasty meal in a tablet; just add water</description>
    </item>
    <item upc="132957764" stock="44">
      <name>Grob winglets</name>
      <price>3.56</price>
      <description>Tender winglets of Grob. Just add water</description>
    </item>

</inventory>""" string>xml "name" deep-tags-named


#javaj#

   <frames> oSal, XML Path sample, 300, 400

#data#

   <xml>
      //<inventory title="OmniCorp Store #45x10^3">
      //

      //    <item upc="123456789" stock="12">
      //      <name>Invisibility Cream</name>
      //      <price>14.50</price>
      //      <description>Makes you invisible</description>
      //    </item>
      //    <item upc="445322344" stock="18">
      //      <name>Levitation Salve</name>
      //      <price>23.99</price>
      //      <description>Levitate yourself for up to 3 hours per application</description>
      //    </item>
      //

      //

      //    <item upc="485672034" stock="653">
      //      <name>Blork and Freen Instameal</name>
      //      <price>4.95</price>
      //      <description>A tasty meal in a tablet; just add water</description>
      //    </item>
      //    <item upc="132957764" stock="44">
      //      <name>Grob winglets</name>
      //      <price>3.56</price>
      //      <description>Tender winglets of Grob. Just add water</description>
      //    </item>
      //

      //</inventory>

   <DEEP_SQL_XML>
      DEEP DB, SELECT, xmelon_data
             ,, path pathStr
             ,, tag tagStr
             ,, patCnt
             ,, dataPlace
             ,, value

#listix#

      //parsing xml data ...
      GEN, :mem datos, xml
      XMELON, FILE2DB, :mem datos
      //
      //first item ...
      //
      //
      LOOP, SQL,, //SELECT patCnt AS patITEM1 FROM (@<DEEP_SQL_XML>) WHERE path_pathStr == '/inventory/section/item' LIMIT 1
          ,HEAD, //<item
          ,, LOOP, SQL,, //SELECT * FROM (@<DEEP_SQL_XML>) WHERE patCnt == @<patITEM1> AND dataPlace == 'A'
          ,,     , LINK, ""
          ,,     ,, // @<tag_tagStr>="@<value>"
          ,, //>
          ,, //
          ,, LOOP, SQL,, //SELECT * FROM (@<DEEP_SQL_XML>) WHERE patCnt == @<patITEM1> AND dataPlace != 'A'
          ,,     ,, //    <@<tag_tagStr>>@<value></@<tag_tagStr>>
          ,TAIL, //
          ,TAIL, //</item>
      //
      //
      //report prices ...
      //
      LOOP, SQL,, //SELECT value FROM (@<DEEP_SQL_XML>) WHERE tag_tagStr == 'price'
          , LINK, ", "
          ,, @<value>
      //
      //put names into a variable
      //
      VAR=, tabnames, "name"
      LOOP, SQL,, //SELECT value FROM (@<DEEP_SQL_XML>) WHERE tag_tagStr == 'name'
          , LINK, ""
          ,, VAR+, tabnames, @<value>
      DUMP, data,, tabnames


package main

import (
	"encoding/xml"
	"fmt"
	"log"
	"os"
)

type Inventory struct {
	XMLName  xml.Name `xml:"inventory"`
	Title    string   `xml:"title,attr"`
	Sections []struct {
		XMLName xml.Name `xml:"section"`
		Name    string   `xml:"name,attr"`
		Items   []struct {
			XMLName     xml.Name `xml:"item"`
			Name        string   `xml:"name"`
			UPC         string   `xml:"upc,attr"`
			Stock       int      `xml:"stock,attr"`
			Price       float64  `xml:"price"`
			Description string   `xml:"description"`
		} `xml:"item"`
	} `xml:"section"`
}

// To simplify main's error handling
func printXML(s string, v interface{}) {
	fmt.Println(s)
	b, err := xml.MarshalIndent(v, "", "\t")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(b))
	fmt.Println()
}

func main() {
	fmt.Println("Reading XML from standard input...")

	var inv Inventory
	dec := xml.NewDecoder(os.Stdin)
	if err := dec.Decode(&inv); err != nil {
		log.Fatal(err)
	}

	// At this point, inv is Go struct with all the fields filled
	// in from the XML data. Well-formed XML input that doesn't
	// match the specification of the fields in the Go struct are
	// discarded without error.

	// We can reformat the parts we parsed:
	//printXML("Got:", inv)

	// 1. Retrieve first item:
	item := inv.Sections[0].Items[0]
	fmt.Println("item variable:", item)
	printXML("As XML:", item)

	// 2. Action on each price:
	fmt.Println("Prices:")
	var totalValue float64
	for _, s := range inv.Sections {
		for _, i := range s.Items {
			fmt.Println(i.Price)
			totalValue += i.Price * float64(i.Stock)
		}
	}
	fmt.Println("Total inventory value:", totalValue)
	fmt.Println()

	// 3. Slice of all the names:
	var names []string
	for _, s := range inv.Sections {
		for _, i := range s.Items {
			names = append(names, i.Name)
		}
	}
	fmt.Printf("names: %q\n", names)
}


def inventory = new XmlSlurper().parseText("<inventory...")    //optionally parseText(new File("inv.xml").text)
def firstItem = inventory.section.item[0]                      //1. first item
inventory.section.item.price.each { println it }               //2. print each price
def allNamesArray = inventory.section.item.name.collect {it}   //3. collect item names into an array


import Data.List
import Control.Arrow
import Control.Monad

takeWhileIncl           :: (a -> Bool) -> [a] -> [a]
takeWhileIncl _ []      =  []
takeWhileIncl p (x:xs)
            | p x       =  x : takeWhileIncl p xs
            | otherwise =  [x]

getmultiLineItem n = takeWhileIncl(not.isInfixOf ("</" ++ n)). dropWhile(not.isInfixOf ('<': n))
getsingleLineItems n = map (takeWhile(/='<'). drop 1. dropWhile(/='>')). filter (isInfixOf ('<': n))

main = do
  xml <- readFile "./Rosetta/xmlpath.xml"
  let xmlText = lines xml

  putStrLn "\n== First item ==\n"
  mapM_ putStrLn $ head $ unfoldr (Just. liftM2 (id &&&) (\\) (getmultiLineItem "item")) xmlText

  putStrLn "\n== Prices ==\n"
  mapM_ putStrLn $ getsingleLineItems "price" xmlText

  putStrLn "\n== Names ==\n"
  print $ getsingleLineItems "name" xmlText


CHARACTER xml*1000, output*1000
  READ(ClipBoard) xml

  EDIT(Text=xml, Right='<item', Right=5, GetPosition=a, Right='</item>', Left, GetPosition=z)
  WRITE(Text=output) xml( a : z), $CRLF

  i = 1
1 EDIT(Text=xml, SetPosition=i, SePaRators='<>', Right='<price>', Word=1, Parse=price, GetPosition=i, ERror=99)
  IF(i > 0) THEN
      WRITE(Text=output, APPend)  'Price element = ', price, $CRLF
      GOTO 1  !  HicEst does not have a "WHILE"
  ENDIF

  EDIT(Text=xml, SPR='<>', R='<name>', W=1, WordEnd=$CR, APpendTo=output, DO=999)
  WRITE(ClipBoard) TRIM(output)


import java.io.StringReader;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class XMLParser {
	final static String xmlStr =
			  "<inventory title=\"OmniCorp Store #45x10^3\">"
			+ "
"
			+ "    <item upc=\"123456789\" stock=\"12\">"
			+ "      <name>Invisibility Cream</name>"
			+ "      <price>14.50</price>"
			+ "      <description>Makes you invisible</description>"
			+ "    </item>"
			+ "    <item upc=\"445322344\" stock=\"18\">"
			+ "      <name>Levitation Salve</name>"
			+ "      <price>23.99</price>"
			+ "      <description>Levitate yourself for up to 3 hours per application</description>"
			+ "    </item>"
			+ "
"
			+ "
"
			+ "    <item upc=\"485672034\" stock=\"653\">"
			+ "      <name>Blork and Freen Instameal</name>"
			+ "      <price>4.95</price>"
			+ "      <description>A tasty meal in a tablet; just add water</description>"
			+ "    </item>"
			+ "    <item upc=\"132957764\" stock=\"44\">"
			+ "      <name>Grob winglets</name>"
			+ "      <price>3.56</price>"
			+ "      <description>Tender winglets of Grob. Just add priwater</description>"
			+ "    </item>"
			+ "
"
			+ "</inventory>";

	public static void main(String[] args) {
		try {
			Document doc = DocumentBuilderFactory.newInstance()
					.newDocumentBuilder()
					.parse(new InputSource(new StringReader(xmlStr)));
			XPath xpath = XPathFactory.newInstance().newXPath();
			// 1
			System.out.println(((Node) xpath.evaluate(
					"/inventory/section/item[1]", doc, XPathConstants.NODE))
					.getAttributes().getNamedItem("upc"));
			// 2, 3
			NodeList nodes = (NodeList) xpath.evaluate(
					"/inventory/section/item/price", doc,
					XPathConstants.NODESET);
			for (int i = 0; i < nodes.getLength(); i++)
				System.out.println(nodes.item(i).getTextContent());
		} catch (Exception e) {
			System.out.println("Error ocurred while parsing XML.");
		}
	}
}


//create XMLDocument object from file
var xhr = new XMLHttpRequest();
xhr.open('GET', 'file.xml', false);
xhr.send(null);
var doc = xhr.responseXML;

//get first <item> element
var firstItem = doc.evaluate( '//item[1]', doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue;
alert( firstItem.textContent );

//output contents of <price> elements
var prices = doc.evaluate( '//price', doc, null, XPathResult.ANY_TYPE, null );
for( var price = prices.iterateNext(); price != null; price = prices.iterateNext() ) {
  alert( price.textContent );
}

//add <name> elements to array
var names = doc.evaluate( '//name', doc, null, XPathResult.ANY_TYPE, null);
var namesArray = [];
for( var name = names.iterateNext(); name != null; name = names.iterateNext() ) {
  namesArray.push( name );
}
alert( namesArray );


using LibExpat

xdoc = raw"""<inventory title="OmniCorp Store #45x10^3">

    <item upc="123456789" stock="12">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>
    <item upc="445322344" stock="18">
      <name>Levitation Salve</name>
      <price>23.99</price>
      <description>Levitate yourself for up to 3 hours per application</description>
    </item>

    <item upc="485672034" stock="653">
      <name>Blork and Freen Instameal</name>
      <price>4.95</price>
      <description>A tasty meal in a tablet; just add water</description>
    </item>
    <item upc="132957764" stock="44">
      <name>Grob winglets</name>
      <price>3.56</price>
      <description>Tender winglets of Grob. Just add water</description>
    </item>

</inventory>
"""

debracket(s) = replace(s, r".+\>(.+)\<.+" => s"\1")

etree = xp_parse(xdoc)
firstshow = LibExpat.find(etree, "//item")[1]
println("The first item's node XML entry is:\n", firstshow, "\n\n")

prices = LibExpat.find(etree, "//price")
println("Prices:")
for p in prices
    println("\t", debracket(string(p)))
end
println("\n")

namearray = LibExpat.find(etree, "//name")
println("Array of names of items:\n\t", map(s -> debracket(string(s)), namearray))


// version 1.1.3

import javax.xml.parsers.DocumentBuilderFactory
import org.xml.sax.InputSource
import java.io.StringReader
import javax.xml.xpath.XPathFactory
import javax.xml.xpath.XPathConstants
import org.w3c.dom.Node
import org.w3c.dom.NodeList

val xml =
"""
<inventory title="OmniCorp Store #45x10^3">

    <item upc="123456789" stock="12">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>
    <item upc="445322344" stock="18">
      <name>Levitation Salve</name>
      <price>23.99</price>
      <description>Levitate yourself for up to 3 hours per application</description>
    </item>

    <item upc="485672034" stock="653">
      <name>Blork and Freen Instameal</name>
      <price>4.95</price>
      <description>A tasty meal in a tablet; just add water</description>
    </item>
    <item upc="132957764" stock="44">
      <name>Grob winglets</name>
      <price>3.56</price>
      <description>Tender winglets of Grob. Just add water</description>
    </item>

</inventory>
"""

fun main(args: Array<String>) {
    val dbFactory = DocumentBuilderFactory.newInstance()
    val dBuilder  = dbFactory.newDocumentBuilder()
    val xmlInput = InputSource(StringReader(xml))
    val doc = dBuilder.parse(xmlInput)
    val xpFactory = XPathFactory.newInstance()
    val xPath = xpFactory.newXPath()

    val qNode = xPath.evaluate("/inventory/section/item[1]", doc, XPathConstants.NODE) as Node
    val upc = qNode.attributes.getNamedItem("upc")
    val stock = qNode.attributes.getNamedItem("stock")
    println("For the first item :  upc = ${upc.textContent} and stock = ${stock.textContent}")

    val qNodes = xPath.evaluate("/inventory/section/item/price", doc, XPathConstants.NODESET) as NodeList
    print("\nThe prices of each item are : ")
    for (i in 0 until qNodes.length) print("${qNodes.item(i).textContent}  ")
    println()

    val qNodes2 = xPath.evaluate("/inventory/section/item/name", doc, XPathConstants.NODESET) as NodeList
    val names = Array<String>(qNodes2.length) { qNodes2.item(it).textContent }
    println("\nThe names of each item are as follows :")
    println("  ${names.joinToString("\n  ")}")
}


#!/bin/ksh

# Perform XPath queries on a XML Document

#	# Variables:
#
typeset -T Xml_t=(
	typeset -h		'UPC'			upc
	typeset -i -h	'num in stock'	stock=0
	typeset -h		'name'			name
	typeset -F2 -h	'price'			price
	typeset -h		'description'	description

	function init_item {
		typeset key ; key="$1"
		typeset val ; val="${2%\<\/${key}*}"

		case ${key} in
			upc)			_.upc="${val//@(\D)/}"
				;;
			stock)			_.stock="${val//@(\D)/}"
				;;
			name)			_.name="${val%\<\/${key}*}"
				;;
			price)			_.price="${val}"
				;;
			description)	_.description=$(echo ${val})
				;;
		esac
	}

	function prt_item {
		print "upc= ${_.upc}"
		print "stock= ${_.stock}"
		print "name= ${_.name}"
		print "price= ${_.price}"
		print "description= ${_.description}"
	}
)

#	# Functions:
#

 ######
# main #
 ######
integer i=0
typeset -a Item_t

buff=$(< xmldoc)	# read xmldoc
item=${buff%%'</item>'*} ; buff=${.sh.match}

while [[ -n ${item} ]]; do
	Xml_t Item_t[i]
	item=${item#*'<item'} ; item=$(echo ${item})
	for word in ${item}; do
		if [[ ${word} == *=* ]]; then
			Item_t[i].init_item ${word%\=*} ${word#*\=}
		else
			if [[ ${word} == \<* ]]; then		# Beginning
				key=${word%%\>*} ; key=${key#*\<}
				val=${word#*\>}
			fi

			[[ ${word} != \<* && ${word} != *\> ]] && val+=" ${word} "

			if [[ ${word} == *\> ]]; then		# End
				val+=" ${word%\<${key}\>*}"
				Item_t[i].init_item "${key}" "${val}"
			fi
		fi
	done
	(( i++ ))
	item=${buff#*'</item>'} ; item=${item%%'</item>'*} ; buff=${.sh.match}
done

print "First Item element:"
Item_t[0].prt_item

typeset -a names
printf "\nList of prices:\n"
for ((i=0; i<${#Item_t[*]}-1; i++)); do
	print ${Item_t[i].price}
	names[i]=${Item_t[i].name}
done

printf "\nArray of names:\n"
for (( i=0; i<${#names[*]}; i++)); do
	print "names[$i] = ${names[i]}"
done


// makes extracting attribute values easier
define xml_attrmap(in::xml_namedNodeMap_attr) => {
	local(out = map)
	with attr in #in
		do #out->insert(#attr->name = #attr->value)
	return #out
}

local(
	text = '<inventory title="OmniCorp Store #45x10^3">

    <item upc="123456789" stock="12">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>
    <item upc="445322344" stock="18">
      <name>Levitation Salve</name>
      <price>23.99</price>
      <description>Levitate yourself for up to 3 hours per application</description>
    </item>

    <item upc="485672034" stock="653">
      <name>Blork and Freen Instameal</name>
      <price>4.95</price>
      <description>A tasty meal in a tablet; just add water</description>
    </item>
    <item upc="132957764" stock="44">
      <name>Grob winglets</name>
      <price>3.56</price>
      <description>Tender winglets of Grob. Just add water</description>
    </item>

</inventory>
',
xml = xml(#text)
)

local(
	items		= #xml -> extract('//item'),
	firstitem	= #items -> first,
	itemattr	= xml_attrmap(#firstitem -> attributes),
	newprices	= array
)

'First item:

UPC: '
#itemattr -> find('upc')
' (stock: '
#itemattr -> find('stock')
')
'
#firstitem -> extractone('name') -> nodevalue
' ['
#firstitem -> extractone('price') -> nodevalue
'] ('
#firstitem -> extractone('description') -> nodevalue
')

'

with item in #items
let name = #item -> extractone('name') -> nodevalue
let price = #item -> extractone('price') -> nodevalue
do {
	#newprices -> insert(#name + ': ' + (decimal(#price) * 1.10) -> asstring(-precision = 2) + ' (' + #price + ')')
}
'Adjusted prices:
'
#newprices -> join('
')
'

'
'Array with all names:
'
#xml -> extract('//name') -> asstaticarray


put revXMLCreateTree(fld "FieldXML",true,true,false) into xmltree

// task 1
put revXMLEvaluateXPath(xmltree,"//item[1]") into nodepath
put revXMLText(xmltree,nodepath,true)

// task 2
put revXMLDataFromXPathQuery(xmltree,"//item/price",,comma)

// task 3
put revXMLDataFromXPathQuery(xmltree,"//name") into namenodes
filter namenodes without empty
split namenodes using cr
put namenodes is an array


require 'lxp'
data = [[<inventory title="OmniCorp Store #45x10^3">

    <item upc="123456789" stock="12">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>
    <item upc="445322344" stock="18">
      <name>Levitation Salve</name>
      <price>23.99</price>
      <description>Levitate yourself for up to 3 hours per application</description>
    </item>

    <item upc="485672034" stock="653">
      <name>Blork and Freen Instameal</name>
      <price>4.95</price>
      <description>A tasty meal in a tablet; just add water</description>
    </item>
    <item upc="132957764" stock="44">
      <name>Grob winglets</name>
      <price>3.56</price>
      <description>Tender winglets of Grob. Just add water</description>
    </item>

</inventory>]]
local first = true
local names, prices = {}, {}
p = lxp.new({StartElement = function (parser, name)
	local a, b, c = parser:pos() --line, offset, pos
	if name == 'item' and first then
		print(data:match('.-</item>', c - b + 1))
		first = false
	end
	if name == 'name' then names[#names+1] = data:match('>(.-)<', c) end
	if name == 'price' then prices[#prices+1] = data:match('>(.-)<', c) end
end})

p:parse(data)
p:close()

print('Name: ', table.concat(names, ', '))
print('Price: ', table.concat(prices, ', '))


example = Import["test.txt", "XML"];
Cases[example, XMLElement["item", _ , _] , Infinity] // First
Cases[example, XMLElement["price", _, List[n_]] -> n, Infinity] // Column
Cases[example, XMLElement["name", _, List[n_]] -> n, Infinity] // Column


/* NetRexx */
options replace format comments java symbols binary

import javax.xml.parsers.
import javax.xml.xpath.
import org.w3c.dom.
import org.w3c.dom.Node
import org.xml.sax.

xmlStr = '' -
  || '<inventory title="OmniCorp Store #45x10^3">' -
  || '
' -
  || '    <item upc="123456789" stock="12">' -
  || '      <name>Invisibility Cream</name>' -
  || '      <price>14.50</price>' -
  || '      <description>Makes you invisible</description>' -
  || '    </item>' -
  || '    <item upc="445322344" stock="18">' -
  || '      <name>Levitation Salve</name>' -
  || '      <price>23.99</price>' -
  || '      <description>Levitate yourself for up to 3 hours per application</description>' -
  || '    </item>' -
  || '
' -
  || '
' -
  || '    <item upc="485672034" stock="653">' -
  || '      <name>Blork and Freen Instameal</name>' -
  || '      <price>4.95</price>' -
  || '      <description>A tasty meal in a tablet; just add water</description>' -
  || '    </item>' -
  || '    <item upc="132957764" stock="44">' -
  || '      <name>Grob winglets</name>' -
  || '      <price>3.56</price>' -
  || '      <description>Tender winglets of Grob. Just add priwater</description>' -
  || '    </item>' -
  || '
' -
  || '</inventory>'

expr1 = '/inventory/section/item[1]'
expr2 = '/inventory/section/item/price'
expr3 = '/inventory/section/item/name'
attr1 = 'upc'

do
  doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(InputSource(StringReader(xmlStr)))
  xpath = XPathFactory.newInstance().newXPath()

  -- Extract attribute from 1st item element
  say expr1
  say "  "(Node xpath.evaluate(expr1, doc, XPathConstants.NODE)).getAttributes().getNamedItem(attr1)
  say

  -- Extract and display all price elments
  nodes = NodeList xpath.evaluate(expr2, doc, XPathConstants.NODESET)
  say expr2
  loop i_ = 0 to nodes.getLength() - 1
    say Rexx(nodes.item(i_).getTextContent()).format(10, 2)
    end i_
  say

  -- Extract elements and store in an ArrayList
  nameList = java.util.List
  nameList = ArrayList()
  nodes = NodeList xpath.evaluate(expr3, doc, XPathConstants.NODESET)
  loop i_ = 0 to nodes.getLength() - 1
    nameList.add(nodes.item(i_).getTextContent())
    end i_

  -- display contents of ArrayList
  say expr3
  loop n_ = 0 to nameList.size() - 1
    say "  "nameList.get(n_)
    end n_
  say

catch ex = Exception
  ex.printStackTrace()
end

return


import sequtils, strutils

const LibXml = "libxml2.so"

type

  XmlDocPtr = pointer

  XmlXPathContextPtr = pointer

  XmlElementKind = enum
    xmlElementNode =      1
    xmlAttributeNode =    2
    xmlTextNode =         3
    xmlCdataSectionNode = 4
    xmlEntityRefNode =    5
    xmlEntityNode =       6
    xmlPiNode =           7
    xmlCommentNode =      8
    xmlDocumentNode =     9
    xmlDocumentTypeNode = 10
    xmlDocumentFragNode = 11
    xmlNotationNode =     12
    xmlHtmlDocumentNode = 13
    xmlDtdNode =          14
    xmlElementDecl =      15
    xmlAttributeDecl =    16
    xmlEntityDecl =       17
    xmlNamespaceDecl =    18
    xmlXincludeStart =    19
    xmlXincludeEnd =      20

  XmlNsKind = XmlElementKind

  XmlNsPtr = ptr XmlNs
  XmlNs = object
    next: XmlNsPtr
    kind: XmlNsKind
    href: cstring
    prefix: cstring
    private: pointer
    context: XmlDocPtr

  XmlAttrPtr = pointer

  XmlNodePtr = ptr XmlNode
  XmlNode = object
    private: pointer
    kind: XmlElementKind
    name: cstring
    children: XmlNodePtr
    last: XmlNodePtr
    parent: XmlNodePtr
    next: XmlNodePtr
    prev: XmlNodePtr
    doc: XmlDocPtr
    ns: XmlNsPtr
    content: cstring
    properties: XmlAttrPtr
    nsDef: XmlNsPtr
    psvi: pointer
    line: cushort
    extra: cushort

  XmlNodeSetPtr = ptr XmlNodeSet
  XmlNodeSet = object
    nodeNr: cint
    nodeMax: cint
    nodeTab: ptr UncheckedArray[XmlNodePtr]

  XmlPathObjectKind = enum
      xpathUndefined
      xpathNodeset
      xpathBoolean
      xpathNumber
      xpathString
      xpathPoint
      xpathRange
      xpathLocationset
      xpathUsers
      xpathXsltTree

  XmlXPathObjectPtr = ptr XmlXPathObject
  XmlXPathObject = object
    kind: XmlPathObjectKind
    nodeSetVal: XmlNodeSetPtr
    boolVal: cint
    floatVal: cdouble
    stringVal: cstring
    user: pointer
    index: cint
    user2: pointer
    index2: cint

  XmlSaveCtxtPtr = pointer

  XmlBufferPtr = pointer

# Declaration of needed "libxml2" procedures.
proc xmlParseFile(docName: cstring): XmlDocPtr
  {.cdecl, dynlib: LibXml, importc: "xmlParseFile".}

proc xmlXPathNewContext(doc: XmlDocPtr): XmlXPathContextPtr
  {.cdecl, dynlib: LibXml, importc: "xmlXPathNewContext".}

proc xmlXPathEvalExpression(str: cstring; ctxt: XmlXPathContextPtr): XmlXPathObjectPtr
  {.cdecl, dynlib: LibXml, importc: "xmlXPathEvalExpression".}

proc xmlXPathFreeContext(ctxt: XmlXPathContextPtr)
  {.cdecl, dynlib: LibXml, importc: "xmlXPathFreeContext".}

proc xmlXPathFreeObject(obj: XmlXPathObjectPtr)
  {.cdecl, dynlib: LibXml, importc: "xmlXPathFreeObject".}

proc xmlSaveToBuffer(vuffer: XmlBufferPtr; encoding: cstring; options: cint): XmlSaveCtxtPtr
  {.cdecl, dynlib: LibXml, importc: "xmlSaveToBuffer".}

proc xmlBufferCreate(): XmlBufferPtr
  {.cdecl, dynlib: LibXml, importc: "xmlBufferCreate".}

proc xmlBufferFree(buf: XmlBufferPtr)
  {.cdecl, dynlib: LibXml, importc: "xmlBufferCreate".}

proc xmlBufferContent(buf: XmlBufferPtr): cstring
  {.cdecl, dynlib: LibXml, importc: "xmlBufferContent".}

proc xmlSaveTree(ctxt: XmlSaveCtxtPtr; cur: XmlNodePtr): clong
  {.cdecl, dynlib: LibXml, importc: "xmlSaveTree".}

proc xmlSaveClose(ctxt: XmlSaveCtxtPtr)
  {.cdecl, dynlib: LibXml, importc: "xmlSaveClose".}

proc `$`(node: XmlNodePtr): string =
  ## Return the representation of a node.
  let buffer = xmlBufferCreate()
  let saveContext = xmlSaveToBuffer(buffer, nil, 0)
  discard saveContext.xmlSaveTree(node)
  saveContext.xmlSaveClose()
  result = $buffer.xmlBufferContent()
  xmlBufferFree(buffer)

iterator nodes(xpath: string; context: XmlXPathContextPtr): XmlNodePtr =
  ## Yield the nodes which fit the XPath request.
  let xpathObj = xmlXPathEvalExpression(xpath, context)
  if xpathObj.isNil:
    quit "Failed to evaluate XPath: " & xpath, QuitFailure
  assert xpathObj.kind == xpathNodeset
  let nodeSet = xpathObj.nodeSetVal
  if not nodeSet.isNil:
    for i in 0..<nodeSet.nodeNr:
      yield nodeSet.nodeTab[i]
  xmlXPathFreeObject(xpathObj)

# Load and parse XML file.
let doc = xmlParseFile("xpath_test.xml")
if doc.isNil:
  quit "Unable to load and parse document", QuitFailure

# Create an XPath context.
let context = xmlXPathNewContext(doc)
if context.isNil:
  quit "Failed to create XPath context", QuitFailure

var xpath = "//section[1]/item[1]"
echo "Request $#:".format(xpath)
for node in nodes(xpath, context):
  echo node
echo()

xpath = "//price/text()"
echo "Request $#:".format(xpath)
for node in nodes(xpath, context):
  echo node.content
echo()

xpath = "//name"
echo "Request $#:".format(xpath)
let names = toSeq(nodes(xpath, context)).mapIt(it.children.content)
echo names

xmlXPathFreeContext(context)


use XML;

bundle Default {
  class Test {
    function : Main(args : String[]) ~ Nil {
      in := String->New();
      in->Append("<inventory title=\"OmniCorp Store #45x10^3\">");
      in->Append("
");
      in->Append("<item upc=\"123456789\" stock=\"12\">");
      in->Append("<name>Invisibility Cream</name>");
      in->Append("<price>14.50</price>");
      in->Append("<description>Makes you invisible</description>");
      in->Append("</item>");
      in->Append("<item upc=\"445322344\" stock=\"18\">");
      in->Append("<name>Levitation Salve</name>");
      in->Append("<price>23.99</price>");
      in->Append("<description>Levitate yourself for up to 3 hours per application</description>");
      in->Append("</item>");
      in->Append("
");
      in->Append("
");
      in->Append("<item upc=\"485672034\" stock=\"653\">");
      in->Append("<name>Blork and Freen Instameal</name>");
      in->Append("<price>4.95</price>");
      in->Append("<description>A tasty meal in a tablet; just add water</description>");
      in->Append("</item>");
      in->Append("<item upc=\"132957764\" stock=\"44\">");
      in->Append("<name>Grob winglets</name>");
      in->Append("<price>3.56</price>");
      in->Append("<description>Tender winglets of Grob. Just add water</description>");
      in->Append("</item>");
      in->Append("
");
      in->Append("</inventory>");

      parser := XmlParser->New(in);
      if(parser->Parse()) {
        # get first item
        results := parser->FindElements("//inventory/section[1]/item[1]");
        if(results <> Nil) {
          IO.Console->Instance()->Print("items: ")->PrintLine(results->Size());
        };
        # get all prices
        results := parser->FindElements("//inventory/section/item/price");
        if(results <> Nil) {
          each(i : results) {
            element := results->Get(i)->As(XMLElement);
            element->GetContent()->PrintLine();
          };
        };
        # get names
        results := parser->FindElements("//inventory/section/item/name");
        if(results <> Nil) {
          IO.Console->Instance()->Print("names: ")->PrintLine(results->Size());
        };
      };
    }
  }
}


declare
  [XMLParser] = {Module.link ['x-oz://system/xml/Parser.ozf']}

  proc {Main Data}
     Parser = {New XMLParser.parser init}
     [Doc] = {Parser parseVS(Data $)}

     FirstItem = {XPath Doc [inventory section item]}.1

     Prices = {XPath Doc [inventory section item price Text]}

     Names = {XPath Doc [inventory section item name]}
  in
     {ForAll Prices System.showInfo}
  end

  %%
  %% Emulation of some XPath functionality:
  %%

  fun {XPath Doc Path}
     P|Pr = Path
  in
     Doc.name = P %% assert
     {FoldL Pr XPathStep [Doc]}
  end

  fun {XPathStep Elements P}
     if {IsProcedure P} then
        {Map Elements P}
     else
        {FilteredChildren Elements P}
     end
  end

  %% A flat list of all Type-children of all Elements.
  fun {FilteredChildren Elements Type}
     {Flatten
      {Map Elements
       fun {$ E}
	  {Filter E.children
	   fun {$ X}
	      case X of element(name:!Type ...) then true
	      else false
	      end
	   end}
       end}}
  end

  %% PCDATA of an element as a ByteString
  fun {Text Element}
     Texts = for Child in Element.children collect:C do
		case Child of text(data:BS ...) then {C BS} end
	     end
  in
     {FoldR Texts ByteString.append {ByteString.make nil}}
  end

  Data =
   "<inventory title=\"OmniCorp Store #45x10^3\">"
  #"
"
  #"    <item upc=\"123456789\" stock=\"12\">"
  #"      <name>Invisibility Cream</name>"
  #"      <price>14.50</price>"
  #"      <description>Makes you invisible</description>"
  #"    </item>"
  #"    <item upc=\"445322344\" stock=\"18\">"
  #"      <name>Levitation Salve</name>"
  #"      <price>23.99</price>"
  #"      <description>Levitate yourself for up to 3 hours per application</description>"
  #"    </item>"
  #"
"
  #"
"
  #"    <item upc=\"485672034\" stock=\"653\">"
  #"      <name>Blork and Freen Instameal</name>"
  #"      <price>4.95</price>"
  #"      <description>A tasty meal in a tablet; just add water</description>"
  #"    </item>"
  #"    <item upc=\"132957764\" stock=\"44\">"
  #"      <name>Grob winglets</name>"
  #"      <price>3.56</price>"
  #"      <description>Tender winglets of Grob. Just add water</description>"
  #"    </item>"
  #"
"
  #"</inventory>"
in
  {Main Data}


use XML::XPath qw();

my $x = XML::XPath->new('<inventory ... </inventory>');

[$x->findnodes('//item[1]')->get_nodelist]->[0];
print $x->findnodes_as_string('//price');
$x->findnodes('//name')->get_nodelist;


include builtins/xml.e
constant xml_txt = """
<inventory title="OmniCorp Store #45x10^3">

    <item upc="123456789" stock="12">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>
    <item upc="445322344" stock="18">
      <name>Levitation Salve</name>
      <price>23.99</price>
      <description>Levitate yourself for up to 3 hours per application</description>
    </item>

    <item upc="485672034" stock="653">
      <name>Blork and Freen Instameal</name>
      <price>4.95</price>
      <description>A tasty meal in a tablet; just add water</description>
    </item>
    <item upc="132957764" stock="44">
      <name>Grob winglets</name>
      <price>3.56</price>
      <description>Tender winglets of Grob. Just add water</description>
    </item>

</inventory>
""",
-- or, of course, xml_txt = get_text("input.xml")
    xml = xml_parse(xml_txt)

sequence sections = xml_get_nodes(xml[XML_CONTENTS],"section"),
         item1 = {},
         prices = {},
         names = {}

for s=1 to length(sections) do
    sequence items = xml_get_nodes(sections[s],"item")
    if item1={} then item1 = items[1] end if
    for i=1 to length(items) do
        prices = append(prices,xml_get_nodes(items[i],"price")[1][XML_CONTENTS])
        names = append(names,xml_get_nodes(items[i],"name")[1][XML_CONTENTS])
    end for
end for

puts(1,"===item[1]===\n")
sequence tmp = xml_new_doc(item1)
puts(1,xml_sprint(tmp))
puts(1,"===prices===\n")
pp(prices)
puts(1,"===names===\n")
pp(names,{pp_Maxlen,90})


<?php
//PHP5 only example due to changes in XML extensions between version 4 and 5 (Tested on PHP5.2.0)
$doc = DOMDocument::loadXML('<inventory title="OmniCorp Store #45x10^3">...</inventory>');
//Load from file instead with $doc = DOMDocument::load('filename');
$xpath = new DOMXPath($doc);
/*
    1st Task: Retrieve the first "item" element
*/
$nodelist = $xpath->query('//item');
$result = $nodelist->item(0);
/*
    2nd task: Perform an action on each "price" element (print it out)
*/
$nodelist = $xpath->query('//price');
for($i = 0; $i < $nodelist->length; $i++)
{
  //print each price element in the DOMNodeList instance, $nodelist, as text/xml followed by a newline
  print $doc->saveXML($nodelist->item($i))."\n";
}
/*
    3rd Task: Get an array of all the "name" elements
*/
$nodelist = $xpath->query('//name');
//our array to hold all the name elements, though in practice you'd probably not need to do this and simply use the DOMNodeList
$result = array();
//a different way of iterating through the DOMNodeList
foreach($nodelist as $node)
{
  $result[] = $node;
}


(load "@lib/xm.l")

(let Sections (body (in "file.xml" (xml)))
   (pretty (car (body (car Sections))))
   (prinl)
   (for S Sections
      (for L (body S)
         (prinl (car (body L 'price))) ) )
   (make
      (for S Sections
         (for L (body S)
            (link (car (body L 'name))) ) ) ) )


$document = [xml]@'
<inventory title="OmniCorp Store #45x10^3">

    <item upc="123456789" stock="12">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>
    <item upc="445322344" stock="18">
      <name>Levitation Salve</name>
      <price>23.99</price>
      <description>Levitate yourself for up to 3 hours per application</description>
    </item>

    <item upc="485672034" stock="653">
      <name>Blork and Freen Instameal</name>
      <price>4.95</price>
      <description>A tasty meal in a tablet; just add water</description>
    </item>
    <item upc="132957764" stock="44">
      <name>Grob winglets</name>
      <price>3.56</price>
      <description>Tender winglets of Grob. Just add water</description>
    </item>

</inventory>
'@

$query = "/inventory/section/item"
$items = $document.SelectNodes($query)


# Python has basic xml parsing built in

from xml.dom import minidom

xmlfile = file("test3.xml") # load xml document from file
xmldoc = minidom.parse(xmlfile).documentElement # parse from file stream or...
xmldoc = minidom.parseString("<inventory title="OmniCorp Store #45x10^3">...</inventory>").documentElement # alternatively, parse a string

#  1st Task: Retrieve the first "item" element
i = xmldoc.getElementsByTagName("item") # get a list of all "item" tags
firstItemElement = i[0] # get the first element

# 2nd task: Perform an action on each "price" element (print it out)
for j in xmldoc.getElementsByTagName("price"): # get a list of all "price" tags
	print j.childNodes[0].data # XML Element . TextNode . data of textnode

# 3rd Task: Get an array of all the "name" elements
namesArray = xmldoc.getElementsByTagName("name")


library("XML")
doc <- xmlInternalTreeParse("test3.xml")

# Retrieve the first "item" element
getNodeSet(doc, "//item")[[1]]

# Perform an action on each "price" element
sapply(getNodeSet(doc, "//price"), xmlValue)

# Get an array of all the "name" elements
sapply(getNodeSet(doc, "//name"), xmlValue)


#lang at-exp racket

(define input @~a{
  <inventory title="OmniCorp Store #45x10^3">

      <item upc="123456789" stock="12">
        <name>Invisibility Cream</name>
        <price>14.50</price>
        <description>Makes you invisible</description>
      </item>
      <item upc="445322344" stock="18">
        <name>Levitation Salve</name>
        <price>23.99</price>
        <description>Levitate yourself for up to 3 hours per application</description>
      </item>

      <item upc="485672034" stock="653">
        <name>Blork and Freen Instameal</name>
        <price>4.95</price>
        <description>A tasty meal in a tablet; just add water</description>
      </item>
      <item upc="132957764" stock="44">
        <name>Grob winglets</name>
        <price>3.56</price>
        <description>Tender winglets of Grob. Just add water</description>
      </item>

  </inventory>})

(require xml xml/path)

(define data (xml->xexpr
              ((eliminate-whitespace '(inventory section item))
               (read-xml/element (open-input-string input)))))

;; Retrieve the first "item" element
(displayln (xexpr->string (se-path* '(item) data)))
;; => <name>Invisibility Cream</name>

;; Perform an action on each "price" element (print it out)
(printf "Prices: ~a\n" (string-join (se-path*/list '(item price) data) ", "))
;; => Prices: 14.50, 23.99, 4.95, 3.56

;; Get an array of all the "name" elements
(se-path*/list '(item name) data)
;; => '("Invisibility Cream" "Levitation Salve" "Blork and Freen Instameal" "Grob winglets")


use XML::XPath;

my $XML = XML::XPath.new(xml => q:to/END/);
<inventory title="OmniCorp Store #45x10^3">

    <item upc="123456789" stock="12">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>
    <item upc="445322344" stock="18">
      <name>Levitation Salve</name>
      <price>23.99</price>
      <description>Levitate yourself for up to 3 hours per application</description>
    </item>

    <item upc="485672034" stock="653">
      <name>Blork and Freen Instameal</name>
      <price>4.95</price>
      <description>A tasty meal in a tablet; just add water</description>
    </item>
    <item upc="132957764" stock="44">
      <name>Grob winglets</name>
      <price>3.56</price>
      <description>Tender winglets of Grob. Just add water</description>
    </item>

</inventory>
END

put "First item:\n", $XML.find('//item[1]')[0];

put "\nPrice elements:";
.contents.put for $XML.find('//price').List;

put "\nName elements:\n", $XML.find('//name')».contents.join: ', ';


import lang::xml::DOM;
import Prelude;

public void get_first_item(loc a){
	D = parseXMLDOM(readFile(a));
	top-down-break visit(D){
		case E:element(_,"item",_): return println(xmlPretty(E));
	};
}

public void print_prices(loc a){
	D = parseXMLDOM(readFile(a));
	for(/element(_,"price",[charData(/str p)]) := D)
		println(p);
}

public list[str] get_names(loc a){
	D = parseXMLDOM(readFile(a));
	L = [];
	for(/element(_,"name",[charData(/str n)]) := D)
		L += n;
	return L;
}


/*REXX program to parse various queries on an XML document  (from a file).    */
iFID='XPATH.XML'                       /*name of the input  XML  file (doc).  */
$=                                     /*string will contain the file's text. */
     do j=1  while  lines(iFID)\==0    /*read the entire file into a string.  */
     $=$ linein(iFID)                  /*append the line to the  $  string.   */
     end   /*j*/
                                       /* [↓]  show 1st  ITEM  in the document*/
parse var $  '<item '  item  "</item>"
say center('first item:',length(space(item)),'─')     /*display a nice header.*/
say space(item)
                                       /* [↓]  show all PRICES in the document*/
prices=                                /*nullify the list and add/append to it*/
$$=$                                   /*start with a fresh copy of document. */
     do  until $$=''                   /* [↓]  keep parsing string until done.*/
     parse var $$  '<price>'   price   '</price>' $$
     prices=prices price               /*add/append the price to the list.    */
     end   /*until*/
say
say center('prices:',length(space(prices)),'─')       /*display a nice header.*/
say space(prices)
                                       /* [↓]  show all  NAMES in the document*/
names.=                                /*nullify the list and add/append to it*/
L=length(' names: ')                   /*maximum length of any one list name. */
$$=$                                   /*start with a fresh copy of document. */
     do #=1  until $$=''               /* [↓]  keep parsing string until done.*/
     parse var $$  '<name>'   names.#   '</name>'   $$
     L=max(L,length(names.#))          /*L:  is used to find the widest name. */
     end   /*#*/

names.0=#-1;                  say      /*adjust the number of names (DO loop).*/
say center('names:',L,'─')             /*display a nicely formatted header.   */
     do k=1  for names.0               /*display all the names in the list.   */
     say names.k                       /*display a name from the  NAMES  list.*/
     end   /*k*/
                                       /*stick a fork in it,  we're all done. */


#Example taken from the REXML tutorial (http://www.germane-software.com/software/rexml/docs/tutorial.html)
require "rexml/document"
include REXML
#create the REXML Document from the string (%q is Ruby's multiline string, everything between the two @-characters is the string)
doc = Document.new(
        %[email protected]<inventory title="OmniCorp Store #45x10^3">
             ...
           </inventory>
          @
                          )
# The invisibility cream is the first <item>
invisibility = XPath.first( doc, "//item" )
# Prints out all of the prices
XPath.each( doc, "//price") { |element| puts element.text }
# Gets an array of all of the "name" elements in the document.
names = XPath.match( doc, "//name" )


scala> val xml: scala.xml.Elem =
     | <inventory title="OmniCorp Store #45x10^3">
     |

     |     <item upc="123456789" stock="12">
     |       <name>Invisibility Cream</name>
     |       <price>14.50</price>
     |       <description>Makes you invisible</description>
     |     </item>
     |     <item upc="445322344" stock="18">
     |       <name>Levitation Salve</name>
     |       <price>23.99</price>
     |       <description>Levitate yourself for up to 3 hours per application</description>
     |     </item>
     |

     |

     |     <item upc="485672034" stock="653">
     |       <name>Blork and Freen Instameal</name>
     |       <price>4.95</price>
     |       <description>A tasty meal in a tablet; just add water</description>
     |     </item>
     |     <item upc="132957764" stock="44">
     |       <name>Grob winglets</name>
     |       <price>3.56</price>
     |       <description>Tender winglets of Grob. Just add water</description>
     |     </item>
     |

     | </inventory>

scala> val firstItem = xml \\ "item" take 1
firstItem: scala.xml.NodeSeq =
NodeSeq(<item upc="123456789" stock="12">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>)

scala> xml \\ "price" map (_.text) foreach println
14.50
23.99
4.95
3.56

scala> val names = (xml \\ "name").toArray
names: Array[scala.xml.Node] = Array(<name>Invisibility Cream</name>, <name>Levitation Salve</name>, <name>Blork and Freen Instameal</name>, <name>Grob winglets</name>)


Set XMLSource to {{
<inventory title="OmniCorp Store #45x10^3">

    <item upc="123456789" stock="12">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>
    <item upc="445322344" stock="18">
      <name>Levitation Salve</name>
      <price>23.99</price>
      <description>Levitate yourself for up to 3 hours per application</description>
    </item>

    <item upc="485672034" stock="653">
      <name>Blork and Freen Instameal</name>
      <price>4.95</price>
      <description>A tasty meal in a tablet; just add water</description>
    </item>
    <item upc="132957764" stock="44">
      <name>Grob winglets</name>
      <price>3.56</price>
      <description>Tender winglets of Grob. Just add water</description>
    </item>

</inventory>
}}

put node "//item[1]" of XMLSource
put node "//price/text()" of XMLSource
put all nodes "//name" of XMLSource


require('XML::XPath');

var x = %s'XML::XPath'.new(ARGF.slurp);

[x.findnodes('//item[1]')][0];
say [x.findnodes('//price')].map{x.getNodeText(_)};
[x.findnodes('//name')];


# assume $xml holds the XML data
package require tdom
set doc [dom parse $xml]
set root [$doc documentElement]

set allNames [$root selectNodes //name]
puts [llength $allNames] ;# ==> 4

set firstItem [lindex [$root selectNodes //item] 0]
puts [$firstItem @upc] ;# ==> 123456789

foreach node [$root selectNodes //price] {
    puts [$node text]
}


$$ MODE TUSCRIPT,{}
MODE DATA
$$ XML=*
<inventory title="OmniCorp Store #45x10³">

    <item upc="123456789" stock="12">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>
    <item upc="445322344" stock="18">
      <name>Levitation Salve</name>
      <price>23.99</price>
      <description>Levitate yourself for up to 3 hours per application</description>
    </item>

    <item upc="485672034" stock="653">
      <name>Blork and Freen Instameal</name>
      <price>4.95</price>
      <description>A tasty meal in a tablet; just add water</description>
    </item>
    <item upc="132957764" stock="44">
      <name>Grob winglets</name>
      <price>3.56</price>
      <description>Tender winglets of Grob. Just add water</description>
    </item>

</inventory>
$$ MODE TUSCRIPT

FILE = "test.xml"
ERROR/STOP CREATE (file,fdf-o,-std-)
FILE/ERASE/UTF8 $FILE = xml

BUILD S_TABLE beg=":<item*>:<name>:<price>:"
BUILD S_TABLE end=":</item>:</name>:</price>:"
BUILD S_TABLE modifiedbeg=":<name>:<price>:"
BUILD S_TABLE modifiedend=":</name>:</price>:"
firstitem=names="",countitem=0
ACCESS q: READ/STREAM/UTF8 $FILE s,a/beg+t+e/end
LOOP
READ/EXIT q
IF (a=="<name>")  names=APPEND(names,t)
IF (a=="<price>") PRINT t
IF (a.sw."<item") countitem=1
IF (countitem==1) THEN
firstitem=CONCAT(firstitem,a)
firstitem=CONCAT(firstitem,t)
firstitem=CONCAT(firstitem,e)
 IF (e=="</item>") THEN
 COUNTITEM=0
 MODIFY ACCESS q s_TABLE modifiedbeg,-,modifiedend
 ENDIF
ENDIF
ENDLOOP
ENDACCESS q
ERROR/STOP CLOSE (file)
firstitem=EXCHANGE (firstitem,":{2-00} ::")
firstitem=INDENT_TAGS (firstitem,-," ")
names=SPLIT(names)
TRACE *firstitem,names


Set objXMLDoc = CreateObject("msxml2.domdocument")

objXMLDoc.load("In.xml")

Set item_nodes = objXMLDoc.selectNodes("//item")
i = 1
For Each item In item_nodes
	If i = 1 Then
		WScript.StdOut.Write item.xml
		WScript.StdOut.WriteBlankLines(2)
		Exit For
	End If
Next

Set price_nodes = objXMLDoc.selectNodes("//price")
list_price = ""
For Each price In price_nodes
	list_price = list_price & price.text & ", "
Next
WScript.StdOut.Write list_price
WScript.StdOut.WriteBlankLines(2)

Set name_nodes = objXMLDoc.selectNodes("//name")
list_name = ""
For Each name In name_nodes
	list_name = list_name & name.text & ", "
Next
WScript.StdOut.Write list_name
WScript.StdOut.WriteBlankLines(2)


Dim first_item = xml.XPathSelectElement("//item")
Console.WriteLine(first_item)

For Each price In xml.XPathSelectElements("//price")
    Console.WriteLine(price.Value)
Next

Dim names = (From item In xml.XPathSelectElements("//name") Select item.Value).ToArray


import "/pattern" for Pattern

var doc = """
<inventory title="OmniCorp Store #45x10^3">

    <item upc="123456789" stock="12">
      <name>Invisibility Cream</name>
      <price>14.50</price>
      <description>Makes you invisible</description>
    </item>
    <item upc="445322344" stock="18">
      <name>Levitation Salve</name>
      <price>23.99</price>
      <description>Levitate yourself for up to 3 hours per application</description>
    </item>

    <item upc="485672034" stock="653">
      <name>Blork and Freen Instameal</name>
      <price>4.95</price>
      <description>A tasty meal in a tablet; just add water</description>
    </item>
    <item upc="132957764" stock="44">
      <name>Grob winglets</name>
      <price>3.56</price>
      <description>Tender winglets of Grob. Just add water</description>
    </item>

</inventory>
"""

var p1 = Pattern.new("<item ")
var match1 = p1.find(doc)
var p2 = Pattern.new("<//item>")
var match2 = p2.find(doc)
System.print("The first 'item' element is:")
System.print("    " + doc[match1.index..match2.index + 6])

var p3 = Pattern.new("<price>[+1^<]<//price>")
var matches = p3.findAll(doc)
System.print("\nThe 'prices' are:")
for (m in matches) System.print(m.captures[0].text)

var p4 = Pattern.new("<name>[+1^<]<//name>")
var matches2 = p4.findAll(doc)
var names = matches2.map { |m| m.captures[0].text }.toList
System.print("\nThe 'names' are:")
System.print(names.join("\n"))


<p:pipeline xmlns:p="http://www.w3.org/ns/xproc"
  name="one-two-three"
  version="1.0">
  <p:identity>
    <p:input port="source">
      <p:inline>
        <root>
          <first/>
          <prices/>
          <names/>
        </root>
      </p:inline>
    </p:input>
  </p:identity>
  <p:insert match="/root/first" position="first-child">
    <p:input port="insertion" select="(//item)[1]">
      <p:pipe port="source" step="one-two-three"/>
    </p:input>
  </p:insert>
  <p:insert match="/root/prices" position="first-child">
    <p:input port="insertion" select="//price">
      <p:pipe port="source" step="one-two-three"/>
    </p:input>
  </p:insert>
  <p:insert match="/root/names" position="first-child">
    <p:input port="insertion" select="//name">
      <p:pipe port="source" step="one-two-three"/>
    </p:input>
  </p:insert>
</p:pipeline>


(:
  1. Retrieve the first "item" element
  Notice the braces around //item. This evaluates first all item elements and then retrieving the first one.
  Whithout the braces you get the first item for every section.
:)
let $firstItem := (//item)[1]

(: 2. Perform an action on each "price" element (print it out) :)
let $price := //price/data(.)

(: 3. Get an array of all the "name" elements  :)
let $names := //name

return
  <result>
    <firstItem>{$firstItem}</firstItem>
    <prices>{$price}</prices>
    <names>{$names}</names>
  </result>


<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" />
  <xsl:template match="/">

    <!-- 1. first item element -->
    <xsl:text>
The first item element is</xsl:text>
    <xsl:value-of select="//item[1]" />

    <!-- 2. Print each price element -->
    <xsl:text>
The prices are: </xsl:text>
    <xsl:for-each select="//price">
      <xsl:text>
      </xsl:text>
      <xsl:copy-of select="." />
    </xsl:for-each>

    <!-- 3. Collect all the name elements -->
    <xsl:text>
The names are: </xsl:text>
    <xsl:copy-of select="//name" />
  </xsl:template>
</xsl:stylesheet>


F yinyang(n = 3)
   V radii = [1, 3, 6].map(i -> i * @n)
   V ranges = radii.map(r -> Array(-r .. r))
   V squares = ranges.map(rnge -> multiloop(rnge, rnge, (x, y) -> (x, y)))
   V circles = zip(squares, radii).map((sqrpoints, radius) -> sqrpoints.filter((x, y) -> x*x + y*y <= @radius^2))
   V m = Dict(squares.last, (x, y) -> ((x, y), ‘ ’))
   L(x, y) circles.last
      m[(x, y)] = ‘*’
   L(x, y) circles.last
      I x > 0
         m[(x, y)] = ‘·’
   L(x, y) circles[(len)-2]
      m[(x, y + 3 * n)] = ‘*’
      m[(x, y - 3 * n)] = ‘·’
   L(x, y) circles[(len)-3]
      m[(x, y + 3 * n)] = ‘·’
      m[(x, y - 3 * n)] = ‘*’
   R ranges.last.map(y -> reversed(@ranges.last).map(x -> @@m[(x, @y)]).join(‘’)).join("\n")

print(yinyang(2))
print(yinyang(1))


pushall: MOVEM.L D0-D7/A0-A6,-(SP)
popall:  MOVEM.L (SP)+,D0-D7/A0-A6
pushWord: MOVE.W <argument>,-(SP)
popWord:  MOVE.W (SP)+,<argument>


INCLUDE "H6:REALMATH.ACT"
INCLUDE "D2:CIRCLE.ACT" ;from the Action! Tool Kit

PROC YinYang(INT x BYTE y BYTE r)
  INT i,a,b,rr,r2,rr2,r5,rr5,y1,y2
  REAL tmp1,tmp2

  Circle(x,y,r,1)

  rr=r*r
  r2=r/2 rr2=rr/4
  Color=1
  FOR i=0 TO r
  DO
    a=rr-i*i
    IntToReal(a,tmp1)
    Sqrt(tmp1,tmp2)
    a=RealToInt(tmp2)

    b=rr2-(i-r2)*(i-r2)
    IntToReal(b,tmp1)
    Sqrt(tmp1,tmp2)
    b=RealToInt(tmp2)

    Plot(x+b,y-i) DrawTo(x+a,y-i)
    Plot(x-b,y+i) DrawTo(x+a,y+i)
  OD

  r5=r/5
  rr5=rr/25
  y1=y-r2 y2=y+r2
  FOR i=0 TO r5
  DO
    a=rr5-i*i
    IntToReal(a,tmp1)
    Sqrt(tmp1,tmp2)
    a=RealToInt(tmp2)

    Color=1
    Plot(x-a,y1-i) DrawTo(x+a,y1-i)
    Plot(x-a,y1+i) DrawTo(x+a,y1+i)

    Color=0
    Plot(x-a,y2-i) DrawTo(x+a,y2-i)
    Plot(x-a,y2+i) DrawTo(x+a,y2+i)
  OD
RETURN

PROC Main()
  BYTE CH=$02FC,COLOR1=$02C5,COLOR2=$02C6

  Graphics(8+16)
  MathInit()
  COLOR1=$00
  COLOR2=$0F

  YinYang(180,120,60)
  YinYang(100,40,30)

  DO UNTIL CH#$FF OD
  CH=$FF
RETURN


with Glib; use Glib;
with Cairo; use Cairo;
with Cairo.Png; use Cairo.Png;
with Cairo.Image_Surface; use Cairo.Image_Surface;

procedure YinYang is
   subtype Dub is Glib.Gdouble;

   procedure Draw (C : Cairo_Context; x : Dub; y : Dub; r : Dub) is begin
      Arc (C, x, y, r + 1.0, 1.571, 7.854);
      Set_Source_Rgb (C, 0.0, 0.0, 0.0); Fill (C);
      Arc_Negative (C, x, y - r / 2.0, r / 2.0, 1.571, 4.712);
      Arc (C, x, y + r / 2.0, r / 2.0, 1.571, 4.712);
      Arc_Negative (C, x, y, r, 4.712, 1.571);
      Set_Source_Rgb (C, 1.0, 1.0, 1.0); Fill (C);
      Arc (C, x, y - r / 2.0, r / 5.0, 1.571, 7.854);
      Set_Source_Rgb (C, 0.0, 0.0, 0.0); Fill (C);
      Arc (C, x, y + r / 2.0, r / 5.0, 1.571, 7.854);
      Set_Source_Rgb (C, 1.0, 1.0, 1.0); Fill (C);
   end Draw;

   Surface : Cairo_Surface;
   Context : Cairo_Context;
   Status : Cairo_Status;
begin
   Surface := Create (Cairo_Format_ARGB32, 200, 200);
   Context := Create (Surface);
   Draw (Context, 120.0, 120.0, 75.0);
   Draw (Context, 35.0, 35.0, 30.0);
   Status := Write_To_Png (Surface, "YinYangAda.png");
   pragma Assert (Status = Cairo_Status_Success);
end YinYang;


INT scale x=2, scale y=1;
CHAR black="#", white=".", clear=" ";

PROC print yin yang = (REAL radius)VOID:(

  PROC in circle = (REAL centre x, centre y, radius, x, y)BOOL:
    (x-centre x)**2+(y-centre y)**2 <= radius**2;

  PROC (REAL, REAL)BOOL
    in big circle = in circle(0, 0, radius, , ),
    in white semi circle  = in circle(0, +radius/2, radius/2, , ),
    in small black circle = in circle(0, +radius/2, radius/6, , ),
    in black semi circle  = in circle(0, -radius/2, radius/2, , ),
    in small white circle = in circle(0, -radius/2, radius/6, , );

  FOR sy FROM +ROUND(radius * scale y) BY -1 TO -ROUND(radius * scale y) DO
    FOR sx FROM -ROUND(radius * scale x) TO +ROUND(radius * scale x) DO
      REAL x=sx/scale x, y=sy/scale y;
      print(
        IF in big circle(x, y) THEN
            IF in white semi circle(x, y) THEN
              IF in small black circle(x, y) THEN black ELSE white FI
            ELIF in black semi circle(x, y) THEN
              IF in small white circle(x, y) THEN white ELSE black FI
            ELIF x < 0 THEN white ELSE black FI
        ELSE
          clear
        FI
      )
    OD;
    print(new line)
  OD
);

main:(
  print yin yang(17);
  print yin yang(8)
)


/* ARM assembly Raspberry PI  */
/*  program yingyang.s   */

/* REMARK 1 : this program use routines in a include file
   see task Include a file language arm assembly
   for the routine affichageMess conversion10
   see at end of this program the instruction include */
/***************************************************************/
/* File Constantes  see task Include a file for arm assembly   */
/***************************************************************/
.include "../constantes.inc"

.equ SIZEMAXI,    78

/******************************************/
/* Initialized data                       */
/******************************************/
.data
szMessDebutPgm:          .asciz "Start program.\n"
szMessFinPgm:            .asciz "Program End ok.\n"
szRetourLigne:            .asciz "\n"

szMessErrComm:           .asciz "Incomplete Command line  : yingyang <size> \n"
/******************************************/
/* UnInitialized data                     */
/******************************************/
.bss
szLine:                .skip SIZEMAXI
/******************************************/
/*  code section                          */
/******************************************/
.text
.global main
main:                           @ entry of program
    mov fp,sp                           // copy stack address  register r29 fp
    ldr r0,iAdrszMessDebutPgm
    bl affichageMess
    ldr r0,[fp]                        // parameter number command line
    cmp r0,#1                          // correct ?
    ble erreurCommande                 // error

    add r0,fp,#8                       // address parameter 2
    ldr r0,[r0]
    bl conversionAtoD
    cmp r0,#SIZEMAXI  / 2
    movgt r0,#(SIZEMAXI / 2) - 1       // limit size
    mov r10,r0                         // size
    lsr r11,r10,#1                     // R = size / 2  radius great circle
    mul r9,r11,r11                     // R^2
    lsr r12,r11,#1                     // radius median circle
    lsr r8,r12,#1                      // radius little circle

    mov r2,#0                          // y
    ldr r0,iAdrszLine
1:
    mov r1,#0                          // x
    mov r5,#' '
    mov r3,#SIZEMAXI
11:                             // move spaces in display line
    strb r5,[r0,r1]
    add r1,#1
    cmp r1,r3
    blt 11b
    mov r1,#0                   // x
2:                              // begin loop
    sub r3,r1,r11               // x1 = x - R
    mul r4,r3,r3                // x1^2
    sub r5,r2,r11               // y1 = y - R
    mul r6,r5,r5                // y1^2
    add r6,r4                   // add x1^2 y1^2
    cmp r6,r9                   // compare R^2
    ble 3f
    mov r5,#' '                 // not in great circle
    strb r5,[r0,r1,lsl #1]
    b 20f
3:                              // compute quadrant
    cmp r1,r11
    bgt 10f                     // x > R
    cmp r2,r11
    bgt 5f                      // y > R
    // quadrant 1  x < R and y < R
    sub r5,r2,r12
    mul r7,r5,r5                // y1^2
    add r7,r4                   // y1^2 + x1^2
    mul r6,r8,r8                // little r ^2
    cmp r7,r8
    bgt 4f
    mov r5,#' '                 // in little circle
    strb r5,[r0,r1,lsl #1]
    b 20f
4:                              // in other part of great circle
    mov r5,#'.'
    strb r5,[r0,r1,lsl #1]
    b 20f
5:  // quadrant 3  x < R and y > R
    mov r5,#3
    mul r5,r10,r5
    lsr r5,#2
    sub r6,r2,r5                // y1 - pos little circle (= (size / 3) * 4
    mul r7,r6,r6                // y1^2
    add r7,r4                   // y1^2 + x1^2
    mul r6,r8,r8                // r little
    cmp r7,r8
    bgt 6f
    mov r5,#' '                 // in little circle
    strb r5,[r0,r1,lsl #1]
    b 20f
6:
    mul r6,r12,r12
    cmp r7,r6
    bge 7f
    mov r5,#'#'                 // in median circle
    strb r5,[r0,r1,lsl #1]
    b 20f
7:
    mov r5,#'.'                 // not in median
    strb r5,[r0,r1,lsl #1]
    b 20f
10:
    cmp r2,r11
    bgt 15f
    // quadrant 2
    sub r5,r2,r12                // y - center little
    mul r6,r5,r5
    add r7,r4,r6
    mul r6,r8,r8
    cmp r7,r6
    bge 11f
    mov r5,#' '                 // in little circle
    strb r5,[r0,r1,lsl #1]
    b 20f
11:
    mul r6,r12,r12
    cmp r7,r6
    bge 12f
    mov r5,#'.'                 // in median circle
    strb r5,[r0,r1,lsl #1]
    b 20f
12:
    mov r5,#'#'                 // in great circle
    strb r5,[r0,r1,lsl #1]
    b 20f
15:
    // quadrant 4
    mov r5,#3
    mul r5,r10,r5
    lsr r5,#2
    sub r6,r2,r5                // y1 - pos little
    mul r7,r6,r6                // y1^2
    add r7,r4                   // y1^2 + x1^2
    mul r6,r8,r8                // little r ^2
    cmp r7,r8
    bgt 16f
    mov r5,#' '                 // in little circle
    strb r5,[r0,r1,lsl #1]
    b 20f
16:
    mov r5,#'#'
    strb r5,[r0,r1,lsl #1]
    b 20f
20:
    add r1,#1                    // increment x
    cmp r1,r10                   // size ?
    ble 2b                       // no -> loop
    lsl r1,#1
    mov r5,#'\n'                 // add return line
    strb r5,[r0,r1]
    add r1,#1
    mov r5,#0                    // add final zéro
    strb r5,[r0,r1]
    bl affichageMess             // and display line
    add r2,r2,#1                 // increment y
    cmp r2,r10                   // size ?
    ble 1b                       // no -> loop

    ldr r0,iAdrszMessFinPgm
    bl affichageMess
    b 100f
erreurCommande:
    ldr r0,iAdrszMessErrComm
    bl affichageMess
    mov r0,#1                    // error code
    b 100f
100:                             // standard end of the program
    mov r0, #0                   // return code
    mov r7, #EXIT                // request to exit program
    svc 0                        // perform the system call
iAdrszMessDebutPgm:         .int szMessDebutPgm
iAdrszMessFinPgm:           .int szMessFinPgm
iAdrszMessErrComm:          .int szMessErrComm
iAdrszLine:                 .int szLine
/***************************************************/
/*      ROUTINES INCLUDE                 */
/***************************************************/
.include "../affichage.inc"


unitsize(1 inch);

fill(scale(6)*unitsquare, invisible);

picture yinyang(pair center, real radius) {
    picture p;
    fill(p, unitcircle, white);
    fill(p, arc(0, S, N) -- cycle, black);
    fill(p, circle(N/2, 1/2), white);
    fill(p, circle(S/2, 1/2), black);
    fill(p, circle(N/2, 1/5), black);
    fill(p, circle(S/2, 1/5), white);
    draw(p, unitcircle, linewidth((1/32) * inch) + gray(0.5));
    return shift(center) * scale(radius) * p;
}

add(yinyang((1 + 1/4, 4 + 3/4), 1));
add(yinyang((3 + 3/4, 2 + 1/4), 2));


Yin_and_Yang(50,  50, A_ScriptDir "\YinYang1.png")
Yin_and_Yang(300, 300,A_ScriptDir "\YinYang2.png")

Yin_and_Yang(width, height, fileName
	, color1=0xFFFFFFFF, color2=0xFF000000, outlineWidth=1){

	pToken 	 := gdip_Startup()
	pBitmap	 := gdip_CreateBitmap(w := width, h := height)
	w-=1, h-=1
	pGraphics:= gdip_GraphicsFromImage(pBitmap)
	pBrushW	 := gdip_BrushCreateSolid(color1)
	pBrushB	 := gdip_BrushCreateSolid(color2)

	gdip_SetSmoothingMode(pGraphics, 4) 			; Antialiasing

	If (outlineWidth){
		pPen := gdip_CreatePen(0xFF000000, outlineWidth)
		gdip_DrawEllipse(pGraphics, pPen, 0, 0, w, h)
		gdip_DeletePen(pPen)
	}

	gdip_FillPie(pGraphics, pBrushB, 0, 0, w, h, -90, 180)
	gdip_FillPie(pGraphics, pBrushW, 0, 0, w, h,  90, 180)
	gdip_FillEllipse(pGraphics, pBrushB, w//4, h//2, w//2, h//2)
	gdip_FillEllipse(pGraphics, pBrushW, w//4, 0   , w//2, h//2)
	gdip_FillEllipse(pGraphics, pBrushB, 5*w//12, h//6, w//6, h//6)
	gdip_FillEllipse(pGraphics, pBrushW, 5*w//12, 4*h//6,w//6,h//6)

	r := gdip_SaveBitmapToFile(pBitmap, filename)

	; cleanup:
	gdip_DeleteBrush(pBrushW), gdip_deleteBrush(pBrushB)
	gdip_DisposeImage(pBitmap)
	gdip_DeleteGraphics(pGraphics)
	gdip_Shutdown(pToken)
	return r
}


# syntax: GAWK -f YIN_AND_YANG.AWK
# converted from PHL
BEGIN {
    yin_and_yang(16)
    yin_and_yang(8)
    exit(0)
}
function yin_and_yang(radius,  black,white,scale_x,scale_y,sx,sy,x,y) {
    black = "#"
    white = "."
    scale_x = 2
    scale_y = 1
    for (sy = radius*scale_y; sy >= -(radius*scale_y); sy--) {
      for (sx = -(radius*scale_x); sx <= radius*scale_x; sx++) {
        x = sx / scale_x
        y = sy / scale_y
        if (in_big_circle(radius,x,y)) {
          if (in_white_semi_circle(radius,x,y)) {
            printf("%s",(in_small_black_circle(radius,x,y)) ? black : white)
          }
          else if (in_black_semi_circle(radius,x,y)) {
            printf("%s",(in_small_white_circle(radius,x,y)) ? white : black)
          }
          else {
            printf("%s",(x<0) ? white : black)
          }
        }
        else {
          printf(" ")
        }
      }
      printf("\n")
    }
}
function in_circle(center_x,center_y,radius,x,y) {
    return (x-center_x)*(x-center_x)+(y-center_y)*(y-center_y) <= radius*radius
}
function in_big_circle(radius,x,y) {
    return in_circle(0,0,radius,x,y)
}
function in_black_semi_circle(radius,x,y) {
    return in_circle(0,0-radius/2,radius/2,x,y)
}
function in_white_semi_circle(radius,x,y) {
    return in_circle(0,radius/2,radius/2,x,y)
}
function in_small_black_circle(radius,x,y) {
    return in_circle(0,radius/2,radius/6,x,y)
}
function in_small_white_circle(radius,x,y) {
    return in_circle(0,0-radius/2,radius/6,x,y)
}


pi=3.141592
s=.5

xp=320:yp=100:size=150
GOSUB DrawYY

xp=500:yp=40:size=50
GOSUB DrawYY

END

DrawYY:
  CIRCLE (xp,yp),size,,,,s
  CIRCLE (xp,yp+size/4),size/8,,,,s
  CIRCLE (xp,yp-size/4),size/8,,,,s
  CIRCLE (xp,yp+size/4),size/2,,.5*pi,1.5*pi,s
  CIRCLE (xp,yp-size/4),size/2,,1.5*pi,2*pi,s
  CIRCLE (xp,yp-size/4),size/2,,0,.5*pi,s
  PAINT (xp,yp-size/4)
  PSET (xp,yp)
  PAINT (xp+size/4,yp)
  RETURN


get "libhdr"

let circle(x, y, c, r) = (r*r) >= (x/2) * (x/2) + (y-c) * (y-c)

let pixel(x, y, r) =
    circle(x, y, -r/2, r/6) -> '#',
    circle(x, y, r/2, r/6)  -> '.',
    circle(x, y, -r/2, r/2) -> '.',
    circle(x, y, r/2, r/2)  -> '#',
    circle(x, y, 0, r)      -> x<0 -> '.', '#',
    ' '

let yinyang(r) be
    for y = -r to r
    $(  for x = -2*r to 2*r do
            wrch(pixel(x,y,r))
        wrch('*N')
    $)

let start() be
$(  yinyang(4)
    yinyang(8)
$)


#include <stdio.h>

void draw_yinyang(int trans, double scale)
{
	printf("<use xlink:href='#y' transform='translate(%d,%d) scale(%g)'/>",
		trans, trans, scale);
}

int main()
{	printf(
	"<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n"
	"<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN'\n"
	"	'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>\n"
	"<svg xmlns='http://www.w3.org/2000/svg' version='1.1'\n"
	"	xmlns:xlink='http://www.w3.org/1999/xlink'\n"
	"		width='30' height='30'>\n"
	"	<defs><g id='y'>\n"
	"		<circle cx='0' cy='0' r='200' stroke='black'\n"
	"			fill='white' stroke-width='1'/>\n"
	"		<path d='M0 -200 A 200 200 0 0 0 0 200\n"
	"			100 100 0 0 0 0 0 100 100 0 0 1 0 -200\n"
	"			z' fill='black'/>\n"
	"		<circle cx='0' cy='100' r='33' fill='white'/>\n"
	"		<circle cx='0' cy='-100' r='33' fill='black'/>\n"
	"	</g></defs>\n");
	draw_yinyang(20, .05);
	draw_yinyang(8, .02);
	printf("</svg>");
	return 0;
}


#include <iostream>

bool circle(int x, int y, int c, int r) {
    return (r * r) >= ((x = x / 2) * x) + ((y = y - c) * y);
}

char pixel(int x, int y, int r) {
    if (circle(x, y, -r / 2, r / 6)) {
        return '#';
    }
    if (circle(x, y, r / 2, r / 6)) {
        return '.';
    }
    if (circle(x, y, -r / 2, r / 2)) {
        return '.';
    }
    if (circle(x, y, r / 2, r / 2)) {
        return '#';
    }
    if (circle(x, y, 0, r)) {
        if (x < 0) {
            return '.';
        } else {
            return '#';
        }
    }
    return ' ';
}

void yinYang(int r) {
    for (int y = -r; y <= r; y++) {
        for (int x = -2 * r; x <= 2 * r; x++) {
            std::cout << pixel(x, y, r);
        }
        std::cout << '\n';
    }
}

int main() {
    yinYang(18);
    return 0;
}