XML/XPath: Difference between revisions

51,742 bytes added ,  1 month ago
Added FreeBASIC
(Added Kotlin)
(Added FreeBASIC)
 
(34 intermediate revisions by 17 users not shown)
Line 2:
 
Perform the following three XPath queries on the XML Document below:
* '''//item[1]''': Retrieve the first "item" element
* '''//price/text()''': Perform an action on each "price" element (print it out)
* '''//name''': Get an array of all the "name" elements
 
XML Document:
Line 33:
</section>
</inventory>
=={{header|AutoHotkey}}==
With regular expressions
<lang AutoHotkey>FileRead, inventory, xmlfile.xml
 
=={{header|AArch64 Assembly}}==
RegExMatch(inventory, "<item.*?</item>", item1)
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
MsgBox % item1
<syntaxhighlight lang="aarch64 assembly">
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program xpathXml64.s */
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.equ NBMAXELEMENTS, 100
/*******************************************/
/* Structures */
/********************************************/
/* structure xmlNode*/
.struct 0
xmlNode_private: // application data
.struct xmlNode_private + 8
xmlNode_type: // type number, must be second !
.struct xmlNode_type + 8
xmlNode_name: // the name of the node, or the entity
.struct xmlNode_name + 8
xmlNode_children: // parent->childs link
.struct xmlNode_children + 8
xmlNode_last: // last child link
.struct xmlNode_last + 8
xmlNode_parent: // child->parent link
.struct xmlNode_parent + 8
xmlNode_next: // next sibling link
.struct xmlNode_next + 8
xmlNode_prev: // previous sibling link
.struct xmlNode_prev + 8
xmlNode_doc: // the containing document
.struct xmlNode_doc + 8
xmlNode_ns: // pointer to the associated namespace
.struct xmlNode_ns + 8
xmlNode_content: // the content
.struct xmlNode_content + 8
xmlNode_properties: // properties list
.struct xmlNode_properties + 8
xmlNode_nsDef: // namespace definitions on this node
.struct xmlNode_nsDef + 8
xmlNode_psvi: // for type/PSVI informations
.struct xmlNode_psvi + 8
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 + 8
xmlNodeSet_fin:
/********************************************/
/* structure xmlXPathObject*/
.struct 0
xmlPathObj_type: //
.struct xmlPathObj_type + 8
xmlPathObj_nodesetval: //
.struct xmlPathObj_nodesetval + 8
xmlPathObj_boolval: //
.struct xmlPathObj_boolval + 8
xmlPathObj_floatval: //
.struct xmlPathObj_floatval + 8
xmlPathObj_stringval: //
.struct xmlPathObj_stringval + 8
xmlPathObj_user: //
.struct xmlPathObj_user + 8
xmlPathObj_index: //
.struct xmlPathObj_index + 8
xmlPathObj_usex2: //
.struct xmlPathObj_usex2 + 8
xmlPathObj_index2: //
.struct xmlPathObj_index2 + 8
/*********************************/
/* 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 8 * NBMAXELEMENTS // result extract area
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
ldr x0,qAdrszFileName
bl xmlParseFile // create doc
cbz x0,99f // error ?
mov x19,x0 // doc address
mov x0,x19 // 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 x0,qAdrszCarriageReturn
bl affichageMess
ldr x0,qAdrszMessDisVal
bl affichageMess
mov x0,x19
ldr x1,qAdrszLibPrice // extract prices
bl extractValue
mov x0,x19
ldr x1,qAdrszLibExtName // extract names
bl extractValue
ldr x0,qAdrszMessDisArea
bl affichageMess
mov x4,#0 // display string result area
ldr x5,qAdrtbExtract
1:
ldr x0,[x5,x4,lsl #3]
cbz x0,2f
bl affichageMess
ldr x0,qAdrszCarriageReturn
bl affichageMess
add x4,x4,1
b 1b
2:
mov x0,x19
bl xmlFreeDoc
bl xmlCleanupParser
ldr x0,qAdrszMessEndpgm
bl affichageMess
b 100f
99: // error
ldr x0,qAdrszMessError
bl affichageMess
100: // standard end of the program
mov x0,0 // return code
mov x8,EXIT // request to exit program
svc 0 // perform the system call
qAdrszMessError: .quad szMessError
qAdrszMessEndpgm: .quad szMessEndpgm
qAdrszLibName: .quad szLibName
qAdrszLibPrice: .quad szLibPrice
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrszFileName: .quad szFileName
qAdrszLibExtName: .quad szLibExtName
qAdrtbExtract: .quad tbExtract
qAdrszMessDisVal: .quad szMessDisVal
qAdrszMessDisArea: .quad szMessDisArea
/******************************************************************/
/* extract value of set */
/******************************************************************/
/* x0 contains the doc address
/* x1 contains the address of the libel to extract */
extractValue:
stp x19,lr,[sp,-16]! // save registers
stp x20,x21,[sp,-16]! // save registers
stp x22,x23,[sp,-16]! // save registers
mov x20,x1 // save address libel
mov x19,x0 // save doc
bl xmlXPathNewContext // create context
mov x23,x0 // save context
mov x1,x0
mov x0,x20
bl xmlXPathEvalExpression
mov x21,x0
mov x0,x23
bl xmlXPathFreeContext // free context
cmp x21,#0
beq 100f
ldr x14,[x21,#xmlPathObj_nodesetval] // values set
ldr w23,[x14,#xmlNodeSet_nodeNr] // set size
mov x22,#0 // index
ldr x20,[x14,#xmlNodeSet_nodeTab] // area of nodes
ldr x21,qAdrtbExtract
1: // start loop
ldr x3,[x20,x22,lsl #3] // load node
mov x0,x19
ldr x1,[x3,#xmlNode_children] // load string value
mov x2,#1
bl xmlNodeListGetString
str x0,[x21,x22,lsl #3] // store string pointer in area
bl affichageMess // and display string result
ldr x0,qAdrszCarriageReturn
bl affichageMess
add x22,x22,1
cmp x22,x23
blt 1b
100:
ldp x22,x23,[sp],16 // restaur 2 registers
ldp x20,x21,[sp],16 // restaur 2 registers
ldp x19,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
{{output}}
<pre>
Invisibility Cream
 
Display set values.
pos = 1
14.50
While, pos := RegExMatch(inventory, "<price>(.*?)</price>", price, pos + 1)
23.99
MsgBox % price1
4.95
3.56
Invisibility Cream
Levitation Salve
Blork and Freen Instameal
Grob winglets
 
Display area values.
While, pos := RegExMatch(inventory, "<name>.*?</name>", name, pos + 1)
Invisibility Cream
names .= name . "`n"
Levitation Salve
MsgBox % names</lang>
Blork and Freen Instameal
{{libheader|AHK XPath}}
Grob winglets
<lang AutoHotkey>#Include xpath.ahk
 
Normal end of program.
xpath_load(doc, "xmlfile.xml")
 
; Retrieve the first "item" element
MsgBox % xpath(doc, "/inventory/section[1]/item[1]/text()")
 
; Perform an action on each "price" element (print it out)
prices := xpath(doc, "/inventory/section/item/price/text()")
Loop, Parse, prices,`,
reordered .= A_LoopField "`n"
MsgBox % reordered
 
; Get an array of all the "name" elements
MsgBox % xpath(doc, "/inventory/section/item/name")</lang>
 
</pre>
 
=={{header|AppleScript}}==
Line 70 ⟶ 284:
''AppleScript has no-built in support for XPath, but it could be used via a 'do shell script' command. Here's a solution using Apple System Events.
 
<langsyntaxhighlight AppleScriptlang="applescript">set theXMLdata to "<inventory title=\"OmniCorp Store #45x10^3\">
<section name=\"health\">
<item upc=\"123456789\" stock=\"12\">
Line 130 ⟶ 344:
return my getElementValuesByName(xmlData's contents, "price") -- Solution to part 3 of problem.
end tell</langsyntaxhighlight>Output for the three results (respectively):<langsyntaxhighlight AppleScriptlang="applescript">"<item upc=\"123456789\" stock=\"12\">
<name>Invisibility Cream</name>
<price>14.50</price>
Line 138 ⟶ 352:
{"Invisibility Cream", "Levitation Salve", "Blork and Freen Instameal", "Grob winglets"}
 
{"14.50", "23.99", "4.95", "3.56"}</langsyntaxhighlight>
 
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
/* 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
 
</syntaxhighlight>
{{output}}
<pre>
Invisibility Cream
 
Display set values.
14.50
23.99
4.95
3.56
Invisibility Cream
Levitation Salve
Blork and Freen Instameal
Grob winglets
 
Display area values.
Invisibility Cream
Levitation Salve
Blork and Freen Instameal
Grob winglets
 
Normal end of program.
 
</pre>
 
=={{header|AutoHotkey}}==
With regular expressions
<syntaxhighlight lang="autohotkey">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</syntaxhighlight>
{{libheader|AHK XPath}}
<syntaxhighlight lang="autohotkey">#Include xpath.ahk
 
xpath_load(doc, "xmlfile.xml")
 
; Retrieve the first "item" element
MsgBox % xpath(doc, "/inventory/section[1]/item[1]/text()")
 
; Perform an action on each "price" element (print it out)
prices := xpath(doc, "/inventory/section/item/price/text()")
Loop, Parse, prices,`,
reordered .= A_LoopField "`n"
MsgBox % reordered
 
; Get an array of all the "name" elements
MsgBox % xpath(doc, "/inventory/section/item/name")</syntaxhighlight>
 
=={{header|Bracmat}}==
<langsyntaxhighlight lang="bracmat">{Retrieve the first "item" element}
( nestML$(get$("doc.xml",X,ML))
: ?
Line 206 ⟶ 712:
?
| out$!anArray {Not truly an array, but a list.}
);</langsyntaxhighlight>
 
=={{header|C}}==
{{libheader|LibXML}}
Takes XML document and XPath expression as inputs and prints results, usage is printed if invoked incorrectly.
<syntaxhighlight lang="c">
#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;
}
</syntaxhighlight>
testXML.xml contains the XML mentioned in the task description. Code must be compiled with the correct flags.
<pre>
C:\rosettaCode>xPather.exe testXML.xml //price
Value 1: 14.50
Value 2: 23.99
Value 3: 4.95
Value 4: 3.56
 
C:\rosettaCode>xPather.exe testXML.xml //name
Value 1: Invisibility Cream
Value 2: Levitation Salve
Value 3: Blork and Freen Instameal
Value 4: Grob winglets
</pre>
 
=={{header|C sharp}}==
<langsyntaxhighlight lang="csharp">XmlReader XReader;
// Either read the xml from a string ...
Line 250 ⟶ 831:
// Convert the generic list to an array and output the count of items.
Console.WriteLine(NodesValues.ToArray().Length);</langsyntaxhighlight>
 
=={{header|C++}}==
 
{{improve|C++|Does not use XPath}}
The following code uses each of the three tasks given to demonstrate a different method of handling the resulting node set from an XPath query.
<lang cpp>#include <vector>
 
#include <string>
{{libheader|LibXML}}
<syntaxhighlight lang="cpp">#include <cassert>
#include <cstdlib>
#include <iostream>
#include <boost/regex.hppstdexcept>
#include <algorithmutility>
#include <iteratorvector>
 
#include <libxml/parser.h>
int main( ) {
#include <libxml/tree.h>
const std::string xmltext(
#include <libxml/xmlerror.h>
"<inventory title=\"OmniCorp Store #45x10^3\">"
#include <libxml/xmlstring.h>
"<section name=\"health\">"
#include <libxml/xmlversion.h>
"<item upc=\"123456789\" stock=\"12\">"
#include <libxml/xpath.h>
"<name>Invisibility Cream</name>"
 
"<price>14.50</price>"
#ifndef LIBXML_XPATH_ENABLED
"<description>Makes you invisible</description>"
# error libxml was not configured with XPath support
"</item>"
#endif
"<item upc=\"445322344\" stock=\"18\">"
 
"<name>Levitation Salve</name>"
// Because libxml2 is a C library, we need a couple things to make it work
"<price>23.99</price>"
// well with modern C++:
"<description>Levitate yourself for up to 3 hours per application</description>"
// 1) a ScopeGuard-like type to handle cleanup functions; and
"</item>"
// 2) an exception type that transforms the library's errors.
"</section>"
 
"<section name=\"food\">"
// ScopeGuard-like type to handle C library cleanup functions.
"<item upc=\"485672034\" stock=\"653\">"
template <typename F>
"<name>Blork and Freen Instameal</name>"
class [[nodiscard]] scope_exit
"<price>4.95</price>"
{
"<description>A tasty meal in a tablet; just add water</description>"
public:
"</item>"
// C++20: Constructor can (and should) be [[nodiscard]].
"<item upc=\"132957764\" stock=\"44\">"
/*[[nodiscard]]*/ constexpr explicit scope_exit(F&& f) :
"<name>Grob winglets</name>"
f_{std::move(f)}
"<price>3.56</price>"
{}
"<description>Tender winglets of Grob. Just add water</description>"
 
"</item>"
~scope_exit()
"</section>"
{
"</inventory>" ) ;
f_();
std::string::size_type found = xmltext.find( "<item" , 0 ) ; //beginning of first item
}
std::string::size_type foundnext = xmltext.find( "</item>" , found + 5 ) ; //and its end
 
std::cout << "The first item is\n" << xmltext.substr( found + 5 , foundnext - ( found + 5 ) ) << '\n' ;
// Non-copyable, non-movable.
std::string::const_iterator start , end ;
scope_exit(scope_exit const&) = delete;
start = xmltext.begin( ) ;
scope_exit(scope_exit&&) = delete;
end = xmltext.end( ) ;
auto operator=(scope_exit const&) -> scope_exit& = delete;
boost::match_results<std::string::const_iterator> what ;
auto operator=(scope_exit&&) -> scope_exit& = delete;
boost::regex pricefind( "<price>(\\d+\\.?\\d+)</price>" ) ;//this regex finds the prices
 
start = xmltext.begin( ) ;
private:
std::cout << "The prices are:\n" ;
F f_;
while ( boost::regex_search( start , end , what , pricefind ) ) {
};
std::string price( what[ 1 ].first , what[ 1 ].second ) ;//find the first price
 
std::cout << price << std::endl ;
// Exception that gets last libxml2 error.
start = what[ 1 ].second ; //continue search after first price found
class libxml_error : public std::runtime_error
}
{
start = xmltext.begin( ) ;
public:
std::vector<std::string> names ;
libxml_error() : libxml_error(std::string{}) {}
boost::regex namefind( "<name>(.+?)</name>" ) ; //find characters, be greedy!
 
while ( boost::regex_search ( start , end , what , namefind ) ) {
explicit libxml_error(std::string name ( what[ 1 ].first , what[ 1 ].second message) ;:
std::runtime_error{make_message_(std::move(message))}
names.push_back( name ) ;
{}
start = what[ 1 ].second ;
 
}
private:
std::cout << "The following name elements were found in the xml string:\n" ;
std::copy( names.begin(static )auto , names.endmake_message_( ) , std::ostream_iterator<std::string message) ->( std::cout , "\n" )) ;string
return 0 ;{
if (auto const last_error = ::xmlGetLastError(); last_error)
}</lang>
{
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;
}
}
</syntaxhighlight>
 
=={{header|Caché ObjectScript}}==
 
<langsyntaxhighlight lang="cos">Class XML.Inventory [ Abstract ]
{
 
Line 387 ⟶ 1,099:
}
 
}</langsyntaxhighlight>
{{out|Examples}}
<pre>
Line 398 ⟶ 1,110:
=={{header|CoffeeScript}}==
<div class='mw-collapsible mw-collapsed'>
<langsyntaxhighlight lang="coffeescript">
doc = new DOMParser().parseFromString '
<inventory title="OmniCorp Store #45x10^3">
Line 427 ⟶ 1,139:
</inventory>
', 'text/xml'
</syntaxhighlight>
</lang>
</div>
<nowiki>#</nowiki> "doc" is the XML as a Document object. Click expand to see parsing code ⇒
 
<langsyntaxhighlight lang="coffeescript">
# Retrieve the first "item" element
doc.evaluate('//item', doc, {}, 7, {}).snapshotItem 0
Line 444 ⟶ 1,156:
names = for i in [0...names.snapshotLength] by 1
names.snapshotItem i
</syntaxhighlight>
</lang>
 
=={{header|ColdFusion}}==
<langsyntaxhighlight lang="cfm"><cfsavecontent variable="xmlString">
<inventory
...
Line 467 ⟶ 1,179:
<cfset names = xmlSearch(xml, "//name")>
<!--- visualize the results --->
<cfdump var="#variables#"></langsyntaxhighlight>
 
=={{header|Common Lisp}}==
Line 474 ⟶ 1,186:
{{libheader|cxml-stp}}
 
<langsyntaxhighlight lang="lisp">(dolist (system '(:xpath :cxml-stp :cxml))
(asdf:oos 'asdf:load-op system))
 
Line 488 ⟶ 1,200:
 
(node-array
(xpath:evaluate "/inventory/section/item/name" *doc*))</langsyntaxhighlight>
 
=={{header|D}}==
It is important to note that the KXML library currently only supports XPath minimally.
{{libheader|KXML}}
<langsyntaxhighlight lang="d">import kxml.xml;
char[]xmlinput =
"<inventory title=\"OmniCorp Store #45x10^3\">
Line 529 ⟶ 1,241:
}
auto namearray = root.parseXPath("inventory/section/item/name");
}</langsyntaxhighlight>
 
=={{header|Delphi}}==
<langsyntaxhighlight Delphilang="delphi">program XMLXPath;
 
{$APPTYPE CONSOLE}
Line 596 ⟶ 1,308:
for s in lItemNames do
Writeln('Item name = ' + s);
end.</langsyntaxhighlight>
 
Output:
<syntaxhighlight lang="text">First item node:
<item upc="123456789" stock="12">
<name>Invisibility Cream</name>
Line 614 ⟶ 1,326:
Item name = Levitation Salve
Item name = Blork and Freen Instameal
Item name = Grob winglets</langsyntaxhighlight>
 
=={{header|E}}==
Line 620 ⟶ 1,332:
{{libheader|E-XML}} (currently a very early work in progress/draft library; design comments welcome)
 
<langsyntaxhighlight lang="e">? def xml__quasiParser := <import:org.switchb.e.xml.makeXMLQuasiParser>()
> def xpath__quasiParser := xml__quasiParser.xPathQuasiParser()
> null
Line 670 ⟶ 1,382:
# xml`<name>Blork and Freen Instameal</name>`,
# xml`<name>Grob winglets</name>`]
</syntaxhighlight>
</lang>
 
=={{header|Erlang}}==
Line 676 ⟶ 1,388:
{{libheader|xmerl}}
 
<langsyntaxhighlight lang="erlang">
-module(xml_xpath).
-include_lib("xmerl/include/xmerl.hrl").
Line 725 ⟶ 1,437:
[ Content#xmlText.value
|| #xmlElement{content = [Content|_]} <- xmerl_xpath:string("//name", Document)].
</syntaxhighlight>
</lang>
 
Output:<pre>First item:
Line 742 ⟶ 1,454:
"Blork and Freen Instameal","Grob winglets"]
</pre>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="vbnet">Dim As String XML, item, price, nombre
Dim As Integer P1, P2
 
'' Read the XML file
Open "test3.xml" For Input As #1
XML = Input(Lof(1), #1)
Close #1
 
'' Find the first 'item' element
P1 = Instr(XML, "<item ")
P2 = Instr(XML, "</item>")
item = Mid(XML, P1, P2-P1+7)
Print "The first 'item' element is:"
Print item
 
'' Find all 'price' elements
Print "The 'prices' are:"
P1 = 1
Do
P1 = Instr(P1, XML, "<price>")
If P1 = 0 Then Exit Do
P2 = Instr(P1, XML, "</price>")
price = Mid(XML, P1+7, P2-P1-7)
Print price
P1 = P2 + 1
Loop
 
'' Find all 'nombre' elements
Print !"\nThe 'names' are:"
P1 = 1
Do
P1 = Instr(P1, XML, "<name>")
If P1 = 0 Then Exit Do
P2 = Instr(P1, XML, "</name>")
nombre = Mid(XML, P1+6, P2-P1-6)
Print nombre
P1 = P2 + 1
Loop
 
Sleep</syntaxhighlight>
 
=={{header|F_Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">
open System.IO
open System.Xml.XPath
Line 787 ⟶ 1,541:
 
// array of all name elements
let names = seq { for name in nav.Select(@"//name") do yield name } |> Seq.toArray</langsyntaxhighlight>
 
=={{header|Factor}}==
Line 794 ⟶ 1,548:
{{libheader|xml.traversal}}
 
<langsyntaxhighlight lang="factor">
 
! Get first item element
Line 879 ⟶ 1,633:
</section>
</inventory>""" string>xml "name" deep-tags-named
</syntaxhighlight>
</lang>
 
=={{header|Gastona}}==
The example uses the command XMELON which parses a XML file of any schema and stores its
contents into db tables. This parser is described in the article [http://web3.codeproject.com/Articles/680642/XMeLon-Schema XMeLon-Schema]
<langsyntaxhighlight lang="gastona">#javaj#
 
<frames> oSal, XML Path sample, 300, 400
Line 962 ⟶ 1,716:
,, VAR+, tabnames, @<value>
DUMP, data,, tabnames
</syntaxhighlight>
</lang>
 
{{out|Output}}
Line 989 ⟶ 1,743:
//Grob winglets
</pre>
 
=={{header|Go}}==
Using the standard <code>encoding/xml</code> package:
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,070 ⟶ 1,825:
}
fmt.Printf("names: %q\n", names)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,093 ⟶ 1,848:
 
{{libheader|xmlpath}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,130 ⟶ 1,885:
fmt.Println("no names")
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,140 ⟶ 1,895:
 
=={{header|Groovy}}==
<langsyntaxhighlight lang="groovy">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</langsyntaxhighlight>
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Data.List
import Control.Arrow
import Control.Monad
Line 1,170 ⟶ 1,925:
putStrLn "\n== Names ==\n"
print $ getsingleLineItems "name" xmlText</langsyntaxhighlight>
Using the Haskell XML Toolkit (HXT):
<langsyntaxhighlight lang="haskell">{-# LANGUAGE Arrows #-}
import Text.XML.HXT.Arrow
{- For HXT version >= 9.0, use instead:
Line 1,189 ⟶ 1,944:
[(item, names)] <- runX (readDocument [] "xmlpath.xml" >>> process)
print item
print names</langsyntaxhighlight>
 
=={{header|HicEst}}==
<langsyntaxhighlight lang="hicest">CHARACTER xml*1000, output*1000
READ(ClipBoard) xml
 
Line 1,206 ⟶ 1,961:
 
EDIT(Text=xml, SPR='<>', R='<name>', W=1, WordEnd=$CR, APpendTo=output, DO=999)
WRITE(ClipBoard) TRIM(output) </langsyntaxhighlight>
<langsyntaxhighlight lang="hicest"> upc="123456789" stock="12">
<name>Invisibility Cream</name>
<price>14.50</price>
Line 1,220 ⟶ 1,975:
Blork and Freen Instameal
Grob winglets
</syntaxhighlight>
</lang>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">import java.io.StringReader;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
Line 1,282 ⟶ 2,037:
}
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
{{works with|Firefox|2.0}}
<langsyntaxhighlight lang="javascript">//create XMLDocument object from file
var xhr = new XMLHttpRequest();
xhr.open('GET', 'file.xml', false);
Line 1,307 ⟶ 2,063:
namesArray.push( name );
}
alert( namesArray );</langsyntaxhighlight>
 
Although some browsers support XPath, working with XML is much easier with E4X.
 
<langsyntaxhighlight lang="javascript">//create XML object from file
var xhr = new XMLHttpRequest();
xhr.open('GET', 'file.xml', false);
Line 1,331 ⟶ 2,087:
names.push( name );
}
alert( names );</langsyntaxhighlight>
 
=={{header|Julia}}==
Uses the LibExpat module for XML pathing. The exercise description is very
vague about output format, so this is varied in the solution below. The first
test prints the raw XML node, and the second and third are further processed.
<syntaxhighlight lang="julia">using LibExpat
 
xdoc = raw"""<inventory title="OmniCorp Store #45x10^3">
<section name="health">
<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>
</section>
<section name="food">
<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>
</section>
</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))
</syntaxhighlight>{{output}}<pre>
The first item's node XML entry is:
<item upc="123456789" stock="12">
<name>Invisibility Cream</name>
<price>14.50</price>
<description>Makes you invisible</description>
</item>
 
 
Prices:
14.50
23.99
4.95
3.56
 
 
Array of names of items:
["Invisibility Cream", "Levitation Salve", "Blork and Freen Instameal", "Grob winglets"]
</pre>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.3
 
import javax.xml.parsers.DocumentBuilderFactory
Line 1,396 ⟶ 2,221:
println("\nThe names of each item are as follows :")
println(" ${names.joinToString("\n ")}")
}</langsyntaxhighlight>
 
{{out}}
Line 1,410 ⟶ 2,235:
Grob winglets
</pre>
 
=={{header|Ksh}}==
<syntaxhighlight lang="ksh">
#!/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</syntaxhighlight>
{{out}}<pre>
First Item element:
upc= 123456789
stock= 12
name= Invisibility Cream
price= 14.50
description= Makes you invisible
 
List of prices:
14.50
23.99
4.95
3.56
 
Array of names:
names[0] = Invisibility Cream
names[1] = Levitation Salve
names[2] = Blork and Freen Instameal
names[3] = Grob winglets</pre>
 
=={{header|Lasso}}==
Lasso has built in support for both XML handling and Xpaths
<langsyntaxhighlight Lassolang="lasso">// makes extracting attribute values easier
define xml_attrmap(in::xml_namedNodeMap_attr) => {
local(out = map)
Line 1,482 ⟶ 2,420:
'<br /><br />'
'<strong>Array with all names:</strong><br />'
#xml -> extract('//name') -> asstaticarray</langsyntaxhighlight>
Output:
<pre>First item:
Line 1,499 ⟶ 2,437:
=={{header|LiveCode}}==
Copy the xml in this task into a text field called "FieldXML"
<langsyntaxhighlight LiveCodelang="livecode">put revXMLCreateTree(fld "FieldXML",true,true,false) into xmltree
 
// task 1
Line 1,512 ⟶ 2,450:
filter namenodes without empty
split namenodes using cr
put namenodes is an array</langsyntaxhighlight>
 
=={{header|Lua}}==
Requires LuaExpat
<langsyntaxhighlight lang="lua">require 'lxp'
data = [[<inventory title="OmniCorp Store #45x10^3">
<section name="health">
Line 1,559 ⟶ 2,497:
 
print('Name: ', table.concat(names, ', '))
print('Price: ', table.concat(prices, ', '))</langsyntaxhighlight>
Output:<pre>
<item upc="123456789" stock="12">
Line 1,570 ⟶ 2,508:
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">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</langsyntaxhighlight>
{{out}}
Output:<pre>
<pre>XMLElement[item,{upc->123456789,stock->12},
{XMLElement[name,{},{Invisibility Cream}],XMLElement[price,{},{14.50}],XMLElement[description,{},{Makes you invisible}]}]
 
14.50
23.99
4.95
3.56
 
Invisibility Cream
Levitation Salve
Blork and Freen Instameal
Grob winglets</pre>
</pre>
 
=={{header|NetRexx}}==
{{trans|Java}}
<langsyntaxhighlight NetRexxlang="netrexx">/* NetRexx */
options replace format comments java crossref symbols binary
 
import javax.xml.parsers.
import javax.xml.xpath.
import org.w3c.dom.
import org.w3c.dom.Node
import org.xml.sax.
 
Line 1,670 ⟶ 2,606:
 
return
</syntaxhighlight>
</lang>
'''Output:'''
<pre>
Line 1,690 ⟶ 2,626:
 
=={{header|Nim}}==
{{libheader|libxml2}}
<lang nim>import xmldom, xmldomparser
Nim standard library provides several modules to process XML, but none to process XPath requests. There is no third party library to do that either.
 
So we provide here a solution which uses the C "libxml2" library. Nim allows to interface with C with a great flexibility. Declaring the external functions is quite easy. The major part of the work consists to declare the data types. In "libxml2" there are a lot of structures and we have translated only what is needed to solve the task (or actually a bit more).
let doc = "test3.xml".loadXMLFile.documentElement
 
For the first request, we use <code>//section[1]/item[1]</code> instead of <code>//item[1]</code> (this is also what the Python version does). The latter request works but it returns the first element in each section which doesn’t seem to be what is expected.
# 1st task: retrieve the first "item" element
let i = doc.getElementsByTagName("item")[0]
 
<syntaxhighlight lang="nim">import sequtils, strutils
# 2nd task: perform an action on each "price" element (print it out)
for j in doc.getElementsByTagName "price":
echo j.firstChild.PText.data
 
const LibXml = "libxml2.so"
# 3rd task: get an array of all the "name" elements
 
let namesArray = doc.getElementsByTagName "name"</lang>
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)</syntaxhighlight>
 
{{out}}
<pre>Request //section[1]/item[1]:
<item upc="123456789" stock="12">
<name>Invisibility Cream</name>
<price>14.50</price>
<description>Makes you invisible</description>
</item>
 
Request //price/text():
14.50
23.99
4.95
3.56
 
Request //name:
@["Invisibility Cream", "Levitation Salve", "Blork and Freen Instameal", "Grob winglets"]</pre>
 
=={{header|Objeck}}==
XPath is used to fetch element tags.
<langsyntaxhighlight lang="objeck">
use XML;
 
Line 1,764 ⟶ 2,896:
}
}
</syntaxhighlight>
</lang>
 
=={{header|Oz}}==
We implement a small subset of XPath for this task:
<langsyntaxhighlight lang="oz">declare
[XMLParser] = {Module.link ['x-oz://system/xml/Parser.ozf']}
 
Line 1,854 ⟶ 2,986:
#"</inventory>"
in
{Main Data}</langsyntaxhighlight>
 
=={{header|Perl}}==
{{libheader|XML::XPath}}
<langsyntaxhighlight lang="perl">use XML::XPath qw();
 
my $x = XML::XPath->new('<inventory ... </inventory>');
Line 1,864 ⟶ 2,996:
[$x->findnodes('//item[1]')->get_nodelist]->[0];
print $x->findnodes_as_string('//price');
$x->findnodes('//name')->get_nodelist;</langsyntaxhighlight>
 
=={{header|Phix}}==
Phix has no direct support for XPath, but achieving the requirements using the standard xml_parse() is not exactly difficult.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">/</span><span style="color: #000000;">xml</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">xml_txt</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
&lt;inventory title="OmniCorp Store #45x10^3"&gt;
&lt;section name="health"&gt;
&lt;item upc="123456789" stock="12"&gt;
&lt;name&gt;Invisibility Cream&lt;/name&gt;
&lt;price&gt;14.50&lt;/price&gt;
&lt;description&gt;Makes you invisible&lt;/description&gt;
&lt;/item&gt;
&lt;item upc="445322344" stock="18"&gt;
&lt;name&gt;Levitation Salve&lt;/name&gt;
&lt;price&gt;23.99&lt;/price&gt;
&lt;description&gt;Levitate yourself for up to 3 hours per application&lt;/description&gt;
&lt;/item&gt;
&lt;/section&gt;
&lt;section name="food"&gt;
&lt;item upc="485672034" stock="653"&gt;
&lt;name&gt;Blork and Freen Instameal&lt;/name&gt;
&lt;price&gt;4.95&lt;/price&gt;
&lt;description&gt;A tasty meal in a tablet; just add water&lt;/description&gt;
&lt;/item&gt;
&lt;item upc="132957764" stock="44"&gt;
&lt;name&gt;Grob winglets&lt;/name&gt;
&lt;price&gt;3.56&lt;/price&gt;
&lt;description&gt;Tender winglets of Grob. Just add water&lt;/description&gt;
&lt;/item&gt;
&lt;/section&gt;
&lt;/inventory&gt;
"""</span><span style="color: #0000FF;">,</span>
<span style="color: #000080;font-style:italic;">-- or, of course, xml_txt = get_text("input.xml")</span>
<span style="color: #000000;">xml</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xml_parse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xml_txt</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">sections</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xml_get_nodes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xml</span><span style="color: #0000FF;">[</span><span style="color: #000000;">XML_CONTENTS</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"section"</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">item1</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span>
<span style="color: #000000;">prices</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span>
<span style="color: #000000;">names</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sections</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">items</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xml_get_nodes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sections</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"item"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">item1</span><span style="color: #0000FF;">={}</span> <span style="color: #008080;">then</span> <span style="color: #000000;">item1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">items</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">items</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">prices</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">prices</span><span style="color: #0000FF;">,</span><span style="color: #000000;">xml_get_nodes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">items</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"price"</span><span style="color: #0000FF;">)[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">XML_CONTENTS</span><span style="color: #0000FF;">])</span>
<span style="color: #000000;">names</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">names</span><span style="color: #0000FF;">,</span><span style="color: #000000;">xml_get_nodes</span><span style="color: #0000FF;">(</span><span style="color: #000000;">items</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"name"</span><span style="color: #0000FF;">)[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">XML_CONTENTS</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"===item[1]===\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tmp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xml_new_doc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">item1</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">xml_sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tmp</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"===prices===\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">prices</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"===names===\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">names</span><span style="color: #0000FF;">,{</span><span style="color: #004600;">pp_Maxlen</span><span style="color: #0000FF;">,</span><span style="color: #000000;">90</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
===item[1]===
<?xml version="1.0" encoding="utf-8" ?>
<item upc="123456789" stock="12">
<name>Invisibility Cream</name>
<price>14.50</price>
<description>Makes you invisible</description>
</item>
===prices===
{`14.50`, `23.99`, `4.95`, `3.56`}
===names===
{`Invisibility Cream`, `Levitation Salve`, `Blork and Freen Instameal`, `Grob winglets`}
</pre>
 
=={{header|PHP}}==
<langsyntaxhighlight lang="php"><?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>');
Line 1,896 ⟶ 3,100:
{
$result[] = $node;
}</langsyntaxhighlight>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(load "@lib/xm.l")
 
(let Sections (body (in "file.xml" (xml)))
Line 1,910 ⟶ 3,114:
(for S Sections
(for L (body S)
(link (car (body L 'name))) ) ) ) )</langsyntaxhighlight>
Output:
<pre>(item
Line 1,925 ⟶ 3,129:
=={{header|PowerShell}}==
Cast the <code>$document</code> string as <code>[xml]</code> and you have access to .NET methods affecting XML.
<syntaxhighlight lang="powershell">
<lang PowerShell>
$document = [xml]@'
<inventory title="OmniCorp Store #45x10^3">
Line 1,957 ⟶ 3,161:
$query = "/inventory/section/item"
$items = $document.SelectNodes($query)
</syntaxhighlight>
</lang>
The first item:
<syntaxhighlight lang="powershell">
<lang PowerShell>
$items[0]
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 1,971 ⟶ 3,175:
</pre>
Get some useful information:
<syntaxhighlight lang="powershell">
<lang PowerShell>
$namesAndPrices = $items | Select-Object -Property name, price
$namesAndPrices
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 1,985 ⟶ 3,189:
</pre>
Here are the prices:
<syntaxhighlight lang="powershell">
<lang PowerShell>
$items.price
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 1,996 ⟶ 3,200:
</pre>
Here are the names:
<syntaxhighlight lang="powershell">
<lang PowerShell>
$items.name
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 2,008 ⟶ 3,212:
 
=={{header|Python}}==
<langsyntaxhighlight lang="python"># Python has basic xml parsing built in
 
from xml.dom import minidom
Line 2,025 ⟶ 3,229:
 
# 3rd Task: Get an array of all the "name" elements
namesArray = xmldoc.getElementsByTagName("name")</langsyntaxhighlight>
In Python 2.5+ you can use ElementTree's limited XPath support
<langsyntaxhighlight lang="python">
import xml.etree.ElementTree as ET
 
Line 2,045 ⟶ 3,249:
 
# list of names
names = doc.findall("section/item/name") # or ".//name"</langsyntaxhighlight>
Or, you can install the <tt>lxml</tt> package and get full XPath support
<langsyntaxhighlight lang="python">
from lxml import etree
 
Line 2,062 ⟶ 3,266:
print "{0:0.2f}".format(float(p.text)) # could raise exception on missing text or invalid float() conversion
 
names = doc.xpath("//name") # list of names</langsyntaxhighlight>
 
=={{header|R}}==
{{libheader|XML (R)}}
<syntaxhighlight lang="r">
<lang R>## Require the XML package you can download from http://www.omegahat.org/RSXML/
library("XML")
doc <- xmlInternalTreeParse("test3.xml")
 
# 1st Task: Retrieve the first "item" element
# Retrieve the first "item" element
(firstItemElement <- getNodeSet(doc, "//item")[[1]])
getNodeSet(doc, "//item")[[1]]
# 2nd task: Perform an action on each "price" element (print it out)
 
prices <- sapply(getNodeSet(doc, "//price"), xmlValue)
# Perform an action on each "price" element
for(i in 1:length(prices)) print(prices[i])
sapply(getNodeSet(doc, "//price"), xmlValue)
# 3rd Task: Get an array of all the "name" elements
 
(namesArray <- sapply(getNodeSet(doc, "//name"), xmlValue))</lang>
# Get an array of all the "name" elements
sapply(getNodeSet(doc, "//name"), xmlValue)
 
</syntaxhighlight>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang at-exp racket
 
Line 2,126 ⟶ 3,334:
(se-path*/list '(item name) data)
;; => '("Invisibility Cream" "Levitation Salve" "Blork and Freen Instameal" "Grob winglets")
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
 
<syntaxhighlight lang="raku" line>use XML::XPath;
 
my $XML = XML::XPath.new(xml => q:to/END/);
<inventory title="OmniCorp Store #45x10^3">
<section name="health">
<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>
</section>
<section name="food">
<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>
</section>
</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: ', ';</syntaxhighlight>
{{out}}
<pre>First item:
<item upc="123456789" stock="12"> <name>Invisibility Cream</name> <price>14.50</price> <description>Makes you invisible</description> </item>
 
Price elements:
14.50
23.99
4.95
3.56
 
Name elements:
Invisibility Cream, Levitation Salve, Blork and Freen Instameal, Grob winglets</pre>
 
=={{header|Rascal}}==
<langsyntaxhighlight lang="rascal">import lang::xml::DOM;
import Prelude;
 
Line 2,151 ⟶ 3,412:
L += n;
return L;
}</langsyntaxhighlight>
Example output:
<langsyntaxhighlight lang="rascal">rascal>get_first_item(|file:///Users/.../Desktop/xmlpath.xml|)
<?xml version="1.0" encoding="UTF-8"?>
<item stock="12" upc="123456789">
Line 2,172 ⟶ 3,433:
 
rascal>get_names(|file:///Users/.../Desktop/xmlpath.xml|)
list[str]: ["Invisibility Cream","Levitation Salve","Blork and Freen Instameal","Grob winglets"]</langsyntaxhighlight>
 
=={{header|REXX}}==
===hard coded parsing===
<langsyntaxhighlight lang="rexx">/*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. */
Line 2,210 ⟶ 3,471:
say names.k /*display a name from the NAMES list.*/
end /*k*/
/*stick a fork in it, we're all done. */</langsyntaxhighlight>
'''output'''
<pre>
Line 2,227 ⟶ 3,488:
 
===generic parsing===
<langsyntaxhighlight lang="rexx">/*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. */
Line 2,258 ⟶ 3,519:
end /*#*/
#=#-1 /*adjust # of thing found.*/
return</langsyntaxhighlight>
'''output''' &nbsp; is the same as the 1<sup>st</sup> version.
 
=={{header|Ruby}}==
{{libheader|REXML}}
<langsyntaxhighlight lang="ruby">#Example taken from the REXML tutorial (http://www.germane-software.com/software/rexml/docs/tutorial.html)
require "rexml/document"
include REXML
Line 2,278 ⟶ 3,539:
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" )</langsyntaxhighlight>
 
=={{header|Scala}}==
The problem description isn't clear on whether what
is wanted is the element or the text. Because of that,
I'm doing both except for the first problem.
 
The commandscode areis beingentered inputtedin intoto Scala's REPL, to
better show the results.
 
<syntaxhighlight lang="scala">
<lang scala>scala> val xml = <inventory title="OmniCorp Store #45x10^3">
scala> val xml: scala.xml.Elem =
| <inventory title="OmniCorp Store #45x10^3">
| <section name="health">
| <item upc="123456789" stock="12">
Line 2,314 ⟶ 3,574:
| </section>
| </inventory>
xml: scala.xml.Elem =
<inventory title="OmniCorp Store #45x10^3">
<section name="health">
<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>
</section>
<section name="food">
<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>
</section>
</inventory>
 
scala> val firstItem = xml \\ "item" headtake 1
firstItem: scala.xml.NodeNodeSeq =
NodeSeq(<item upc="123456789" stock="12">
<name>Invisibility Cream</name>
<price>14.50</price>
<description>Makes you invisible</description>
</item>)
 
scala> xml \\ "price" foreach println
<price>14.50</price>
<price>23.99</price>
<price>4.95</price>
<price>3.56</price>
 
scala> xml \\ "price" map (_ .text) foreach println
14.50
23.99
Line 2,362 ⟶ 3,589:
3.56
 
scala> val elementsnames = (xml \\ "name" ).toArray
elementsnames: Array[scala.xml.Node] = Array(<name>Invisibility Cream</name>, <name>Levitation Salve</name>, <name>Blork and Freen Instameal</name>, <name>Grob winglets</name>)</syntaxhighlight>
Freen Instameal</name>, <name>Grob winglets</name>)
 
=={{header|SenseTalk}}==
scala> val values = xml \\ "name" map (_ text) toArray
<syntaxhighlight lang="sensetalk">Set XMLSource to {{
values: Array[String] = Array(Invisibility Cream, Levitation Salve, Blork and Freen Instameal, Grob winglets)</lang>
<inventory title="OmniCorp Store #45x10^3">
<section name="health">
<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>
</section>
<section name="food">
<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>
</section>
</inventory>
}}
 
put node "//item[1]" of XMLSource
put node "//price/text()" of XMLSource
put all nodes "//name" of XMLSource</syntaxhighlight>
 
{{out}}
<pre>
<item upc="123456789" stock="12">
<name>Invisibility Cream</name>
<price>14.50</price>
<description>Makes you invisible</description>
</item>
14.50
(<name>Invisibility Cream</name>,<name>Levitation Salve</name>,<name>Blork and Freen Instameal</name>,<name>Grob winglets</name>)
</pre>
 
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">require('XML::XPath');
 
var x = %s'XML::XPath'.new(ARGF.slurp);
Line 2,377 ⟶ 3,645:
[x.findnodes('//item[1]')][0];
say [x.findnodes('//price')].map{x.getNodeText(_)};
[x.findnodes('//name')];</langsyntaxhighlight>
 
{{out}}
Line 2,386 ⟶ 3,654:
=={{header|Tcl}}==
{{libheader|tDOM}}
<langsyntaxhighlight lang="tcl"># assume $xml holds the XML data
package require tdom
set doc [dom parse $xml]
Line 2,399 ⟶ 3,667:
foreach node [$root selectNodes //price] {
puts [$node text]
}</langsyntaxhighlight>
 
=={{header|TUSCRIPT}}==
<langsyntaxhighlight lang="tuscript">
$$ MODE TUSCRIPT,{}
MODE DATA
Line 2,464 ⟶ 3,733:
names=SPLIT(names)
TRACE *firstitem,names
</syntaxhighlight>
</lang>
Output:
<pre style='height:30ex;overflow:scroll'>
Line 2,486 ⟶ 3,755:
 
=={{header|VBScript}}==
<syntaxhighlight lang="vb">
<lang vb>
Set objXMLDoc = CreateObject("msxml2.domdocument")
 
Line 2,516 ⟶ 3,785:
WScript.StdOut.Write list_name
WScript.StdOut.WriteBlankLines(2)
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,532 ⟶ 3,801:
=={{header|Visual Basic .NET}}==
 
<langsyntaxhighlight lang="vbnet">Dim first_item = xml.XPathSelectElement("//item")
Console.WriteLine(first_item)
Line 2,539 ⟶ 3,808:
Next
Dim names = (From item In xml.XPathSelectElements("//name") Select item.Value).ToArray</langsyntaxhighlight>
 
=={{header|Wren}}==
{{libheader|Wren-pattern}}
Wren does not have built-in support for XML/XPath and, to my knowledge, there is no third party module which adds such support either. We therefore have to fall back on string pattern matching to perform the required queries.
<syntaxhighlight lang="wren">import "./pattern" for Pattern
 
var doc = """
<inventory title="OmniCorp Store #45x10^3">
<section name="health">
<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>
</section>
<section name="food">
<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>
</section>
</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"))</syntaxhighlight>
 
{{out}}
<pre>
The first 'item' element is:
<item upc="123456789" stock="12">
<name>Invisibility Cream</name>
<price>14.50</price>
<description>Makes you invisible</description>
</item>
 
The 'prices' are:
14.50
23.99
4.95
3.56
 
The 'names' are:
Invisibility Cream
Levitation Salve
Blork and Freen Instameal
Grob winglets
</pre>
<br>
{{libheader|Wren-xsequence}}
Since the first version was written, the above XML parser has appeared. Consequently, the solution can now be rewritten as follows, the output being the same as before.
 
Note that this library doesn't support XPath as such though for this particular task simple 'for' statements suffice.
<syntaxhighlight lang="wren">import "./xsequence" for XDocument
 
var xml = """
<inventory title="OmniCorp Store #45x10^3">
<section name="health">
<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>
</section>
<section name="food">
<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>
</section>
</inventory>
"""
 
var doc = XDocument.parse(xml)
System.print("The first 'item' element is:")
System.print(doc.root.element("section").element("item"))
 
var prices = []
var names = []
for (el in doc.root.elements) {
for (el2 in el.elements) {
prices.add(el2.element("price").value)
names.add(el2.element("name").value)
}
}
System.print("\nThe 'prices' are:\n%(prices.join("\n"))")
System.print("\nThe 'names' are:\n%(names.join("\n"))")</syntaxhighlight>
 
=={{header|XPL0}}==
To run: xml <xml.xml
<syntaxhighlight lang "XPL0">include xpllib; \for StrFind
 
char XML(1000000), P, P1, P2, Addr;
int I, Ch;
[I:= 0;
loop [Ch:= ChIn(1);
XML(I):= Ch;
if Ch = $1A \EOF\ then quit;
I:= I+1;
];
XML(I):= 0;
 
P1:= StrFind(XML, "<item ");
P2:= StrFind(XML, "</item>");
Text(0, "The first 'item' element is:^m^j");
for P:= P1 to P2+6 do ChOut(0, P(0));
CrLf(0);
 
Text(0, "^m^jThe 'prices' are:^m^j");
Addr:= XML;
loop [P1:= StrFind(Addr, "<price>");
if P1 = 0 then quit;
P2:= StrFind(Addr, "</price>");
if P2 = 0 then quit;
for P:= P1+7 to P2-1 do ChOut(0, P(0));
CrLf(0);
Addr:= P2+1;
];
Text(0, "^m^jThe 'names' are:^m^j");
Addr:= XML;
loop [P1:= StrFind(Addr, "<name>");
if P1 = 0 then quit;
P2:= StrFind(Addr, "</name>");
if P2 = 0 then quit;
for P:= P1+6 to P2-1 do ChOut(0, P(0));
CrLf(0);
Addr:= P2+1;
];
]</syntaxhighlight>
{{out}}
<pre>
The first 'item' element is:
<item upc="123456789" stock="12">
<name>Invisibility Cream</name>
<price>14.50</price>
<description>Makes you invisible</description>
</item>
 
The 'prices' are:
14.50
23.99
4.95
3.56
 
The 'names' are:
Invisibility Cream
Levitation Salve
Blork and Freen Instameal
Grob winglets
</pre>
 
=={{header|XProc}}==
<langsyntaxhighlight lang="xml"><p:pipeline xmlns:p="http://www.w3.org/ns/xproc"
name="one-two-three"
version="1.0">
Line 2,572 ⟶ 4,027:
</p:input>
</p:insert>
</p:pipeline></langsyntaxhighlight>
 
=={{header|XQuery}}==
<langsyntaxhighlight lang="xquery">(:
1. Retrieve the first "item" element
Notice the braces around //item. This evaluates first all item elements and then retrieving the first one.
Line 2,592 ⟶ 4,048:
<prices>{$price}</prices>
<names>{$names}</names>
</result></langsyntaxhighlight>
 
Performing this XQuery on the given input document results in
<langsyntaxhighlight lang="xquery"><?xml version="1.0" encoding="UTF-8"?>
<result>
<firstItem>
Line 2,611 ⟶ 4,067:
<name>Grob winglets</name>
</names>
</result></langsyntaxhighlight>
 
=={{header|XSLT}}==
<langsyntaxhighlight lang="xml"><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="/">
Line 2,637 ⟶ 4,093:
<xsl:copy-of select="//name" />
</xsl:template>
</xsl:stylesheet></langsyntaxhighlight>
 
{{omit from|Batch File|No way of XML parsing or processing.}}
2,122

edits