XML/XPath: Difference between revisions

From Rosetta Code
< XML
Content added Content deleted
(added Haskell (without using specialized modules))
m (Fixed lang tags.)
Line 35: Line 35:
=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
With regular expressions
With regular expressions
<lang AutoHotkey>
<lang AutoHotkey>FileRead, inventory, xmlfile.xml
FileRead, inventory, xmlfile.xml


RegExMatch(inventory, "<item.*?</item>", item1)
RegExMatch(inventory, "<item.*?</item>", item1)
Line 47: Line 46:
While, pos := RegExMatch(inventory, "<name>.*?</name>", name, pos + 1)
While, pos := RegExMatch(inventory, "<name>.*?</name>", name, pos + 1)
names .= name . "`n"
names .= name . "`n"
MsgBox % names
MsgBox % names</lang>
</lang>
{{libheader|AHK XPath}}
{{libheader|AHK XPath}}
<lang AutoHotkey>
<lang AutoHotkey>#Include xpath.ahk
#Include xpath.ahk


xpath_load(doc, "xmlfile.xml")
xpath_load(doc, "xmlfile.xml")
Line 65: Line 62:


; Get an array of all the "name" elements
; Get an array of all the "name" elements
MsgBox % xpath(doc, "/inventory/section/item/name")
MsgBox % xpath(doc, "/inventory/section/item/name")</lang>
</lang>


=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==
<lang csharp> XmlReader XReader;
<lang csharp>XmlReader XReader;
// Either read the xml from a string ...
// Either read the xml from a string ...
XReader = XmlReader.Create(new StringReader("<inventory title=... </inventory>"));
XReader = XmlReader.Create(new StringReader("<inventory title=... </inventory>"));
// ... or read it from the file system.
// ... or read it from the file system.
XReader = XmlReader.Create("xmlfile.xml");
XReader = XmlReader.Create("xmlfile.xml");
// Create a XPathDocument object (which implements the IXPathNavigable interface)
// Create a XPathDocument object (which implements the IXPathNavigable interface)
// which is optimized for XPath operation. (very fast).
// which is optimized for XPath operation. (very fast).
IXPathNavigable XDocument = new XPathDocument(XReader);
IXPathNavigable XDocument = new XPathDocument(XReader);
// Create a Navigator to navigate through the document.
// Create a Navigator to navigate through the document.
XPathNavigator Nav = XDocument.CreateNavigator();
XPathNavigator Nav = XDocument.CreateNavigator();
Nav = Nav.SelectSingleNode("//item");
Nav = Nav.SelectSingleNode("//item");
// Move to the first element of the selection. (if available).
// Move to the first element of the selection. (if available).
if(Nav.MoveToFirst())
if(Nav.MoveToFirst())
{
{
Console.WriteLine(Nav.OuterXml); // The outer xml of the first item element.
Console.WriteLine(Nav.OuterXml); // The outer xml of the first item element.
}
}
// Get an iterator to loop over multiple selected nodes.
// Get an iterator to loop over multiple selected nodes.
XPathNodeIterator Iterator = XDocument.CreateNavigator().Select("//price");
XPathNodeIterator Iterator = XDocument.CreateNavigator().Select("//price");
while (Iterator.MoveNext())
while (Iterator.MoveNext())
{
{
Console.WriteLine(Iterator.Current.Value);
Console.WriteLine(Iterator.Current.Value);
}
}
Iterator = XDocument.CreateNavigator().Select("//name");
Iterator = XDocument.CreateNavigator().Select("//name");
// Use a generic list.
// Use a generic list.
List<string> NodesValues = new List<string>();
List<string> NodesValues = new List<string>();
while (Iterator.MoveNext())
while (Iterator.MoveNext())
{
{
NodesValues.Add(Iterator.Current.Value);
NodesValues.Add(Iterator.Current.Value);
}
}
// Convert the generic list to an array and output the count of items.
// Convert the generic list to an array and output the count of items.
Console.WriteLine(NodesValues.ToArray().Length);</lang>
Console.WriteLine(NodesValues.ToArray().Length);</lang>


=={{header|C++}}==
=={{header|C++}}==
<lang C++>#include <vector>
<lang cpp>#include <vector>
#include <string>
#include <string>
#include <iostream>
#include <iostream>
Line 174: Line 170:
std::copy( names.begin( ) , names.end( ) , std::ostream_iterator<std::string>( std::cout , "\n" )) ;
std::copy( names.begin( ) , names.end( ) , std::ostream_iterator<std::string>( std::cout , "\n" )) ;
return 0 ;
return 0 ;
}</lang>
}
</lang>


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


=={{header|D}}==
=={{header|D}}==
It is important to note that the KXML library currently only supports XPath minimally.
It is important to note that the KXML library currently only supports XPath minimally.
{{libheader|KXML}}
{{libheader|KXML}}
<lang d>
<lang d>import kxml.xml;
import kxml.xml;
char[]xmlinput =
char[]xmlinput =
"<inventory title=\"OmniCorp Store #45x10^3\">
"<inventory title=\"OmniCorp Store #45x10^3\">
Line 240: Line 234:
}
}
auto namearray = root.parseXPath("inventory/section/item/name");
auto namearray = root.parseXPath("inventory/section/item/name");
}</lang>
}

</lang>


=={{header|Groovy}}==
=={{header|Groovy}}==
Line 279: Line 271:
=={{header|JavaScript}}==
=={{header|JavaScript}}==
{{works with|Firefox|2.0}}
{{works with|Firefox|2.0}}
<lang javascript> //create XMLDocument object from file
<lang javascript>//create XMLDocument object from file
var xhr = new XMLHttpRequest();
var xhr = new XMLHttpRequest();
xhr.open('GET', 'file.xml', false);
xhr.open('GET', 'file.xml', false);
xhr.send(null);
xhr.send(null);
var doc = xhr.responseXML;
var doc = xhr.responseXML;

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

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

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


Although some browsers support XPath, working with XML is much easier with E4X.
Although some browsers support XPath, working with XML is much easier with E4X.


<lang javascript> //create XML object from file
<lang javascript>//create XML object from file
var xhr = new XMLHttpRequest();
var xhr = new XMLHttpRequest();
xhr.open('GET', 'file.xml', false);
xhr.open('GET', 'file.xml', false);
xhr.send(null);
xhr.send(null);
var doc = new XML(xhr.responseText);
var doc = new XML(xhr.responseText);

//get first <item> element
//get first <item> element
var firstItem = doc..item[0];
var firstItem = doc..item[0];
alert( firstItem );
alert( firstItem );

//output contents of <price> elements
//output contents of <price> elements
for each( var price in doc..price ) {
for each( var price in doc..price ) {
alert( price );
alert( price );
}
}

//add <name> elements to array
//add <name> elements to array
var names = [];
var names = [];
for each( var name in doc..name ) {
for each( var name in doc..name ) {
names.push( name );
names.push( name );
}
}
alert( names );</lang>
alert( names );</lang>


=={{header|Perl}}==
=={{header|Perl}}==
{{libheader|XML::XPath}}
{{libheader|XML::XPath}}
<lang perl> use XML::XPath qw();
<lang perl>use XML::XPath qw();

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

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


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


=={{header|Python}}==
=={{header|Python}}==
<lang python>
<lang python># Python has basic xml parsing built in
# Python has basic xml parsing built in


from xml.dom import minidom
from xml.dom import minidom
Line 390: Line 379:


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


=={{header|R}}==
=={{header|R}}==
{{libheader|XML (R)}}
{{libheader|XML (R)}}
<lang R>## Require the XML package you can download from http://www.omegahat.org/RSXML/
<lang R>
## Require the XML package you can download from http://www.omegahat.org/RSXML/
library("XML")
library("XML")
doc <- xmlInternalTreeParse("test3.xml")
doc <- xmlInternalTreeParse("test3.xml")
Line 405: Line 392:
for(i in 1:length(prices)) print(prices[i])
for(i in 1:length(prices)) print(prices[i])
# 3rd Task: Get an array of all the "name" elements
# 3rd Task: Get an array of all the "name" elements
(namesArray <- sapply(getNodeSet(doc, "//name"), xmlValue))
(namesArray <- sapply(getNodeSet(doc, "//name"), xmlValue))</lang>

</lang>


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


=={{header|Scala}}==
=={{header|Scala}}==
Line 436: Line 421:
better show the results.
better show the results.


<lang scala>scala> val xml = <inventory title="OmniCorp Store #45x10^3">
<lang scala>
scala> val xml = <inventory title="OmniCorp Store #45x10^3">
| <section name="health">
| <section name="health">
| <item upc="123456789" stock="12">
| <item upc="123456789" stock="12">
Line 516: Line 500:


scala> val values = xml \\ "name" map (_ text) toArray
scala> val values = xml \\ "name" map (_ text) toArray
values: Array[String] = Array(Invisibility Cream, Levitation Salve, Blork and Freen Instameal, Grob winglets)
values: Array[String] = Array(Invisibility Cream, Levitation Salve, Blork and Freen Instameal, Grob winglets)</lang>
</lang>


=={{header|Tcl}}==
=={{header|Tcl}}==
Line 538: Line 521:
=={{header|Visual Basic .NET}}==
=={{header|Visual Basic .NET}}==


Dim first_item = xml.XPathSelectElement("//item")
<lang vbnet>Dim first_item = xml.XPathSelectElement("//item")
Console.WriteLine(first_item)
Console.WriteLine(first_item)
For Each price In xml.XPathSelectElements("//price")
For Each price In xml.XPathSelectElements("//price")
Console.WriteLine(price.Value)
Console.WriteLine(price.Value)
Next
Next
Dim names = (From item In xml.XPathSelectElements("//name") Select item.Value).ToArray
Dim names = (From item In xml.XPathSelectElements("//name") Select item.Value).ToArray</lang>




=={{header|XQuery}}==
=={{header|XQuery}}==
<lang xquery>
<lang xquery>(:

(:
1. Retrieve the first "item" element
1. Retrieve the first "item" element
Notice the braces around //item. This evaluates first all item elements and then retrieving the first one.
Notice the braces around //item. This evaluates first all item elements and then retrieving the first one.
Line 569: Line 550:
<prices>{$price}</prices>
<prices>{$price}</prices>
<names>{$names}</names>
<names>{$names}</names>
</result>
</result></lang>
</lang>


Performing this XQuery on the given input document results in
Performing this XQuery on the given input document results in
<lang xquery><?xml version="1.0" encoding="UTF-8"?>
<lang>
<?xml version="1.0" encoding="UTF-8"?>
<result>
<result>
<firstItem>
<firstItem>
Line 590: Line 569:
<name>Grob winglets</name>
<name>Grob winglets</name>
</names>
</names>
</result>
</result></lang>

</lang>


=={{header|XSLT}}==
=={{header|XSLT}}==
<lang xml><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<pre><nowiki>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:output method="text" />
<xsl:template match="/">
<xsl:template match="/">
Line 619: Line 595:
<xsl:copy-of select="//name" />
<xsl:copy-of select="//name" />
</xsl:template>
</xsl:template>
</xsl:stylesheet>
</xsl:stylesheet></lang>
</nowiki></pre>

Revision as of 19:03, 22 November 2009

Task
XML/XPath
You are encouraged to solve this task according to the task description, using any language you may know.

Perform the following three XPath queries on the XML Document below:

  • Retrieve the first "item" element
  • Perform an action on each "price" element (print it out)
  • Get an array of all the "name" elements

XML Document:

<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>

AutoHotkey

With regular expressions <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</lang>

Library: AHK XPath

<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")</lang>

C#

<lang csharp>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);</lang>

C++

<lang cpp>#include <vector>

  1. include <string>
  2. include <iostream>
  3. include <boost/regex.hpp>
  4. include <algorithm>
  5. include <iterator>

int main( ) {

  const std::string xmltext( 
     "<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>" ) ;
  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' ;
  std::string::const_iterator start , end ;
  start = xmltext.begin( ) ;
  end = xmltext.end( ) ;
  boost::match_results<std::string::const_iterator> what ;
  boost::regex pricefind( "<price>(\\d+\\.?\\d+)</price>" ) ;//this regex finds the prices
  start = xmltext.begin( ) ;
  std::cout << "The prices are:\n" ;
  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 ;                        
     start = what[ 1 ].second ;                               //continue search after first price found
  }
  start = xmltext.begin( ) ;
  std::vector<std::string> names ;
  boost::regex namefind( "<name>(.+?)</name>" ) ;            //find characters, be greedy!
  while ( boost::regex_search ( start , end , what , namefind ) ) {
     std::string name ( what[ 1 ].first , what[ 1 ].second ) ;
     names.push_back( name ) ;
     start = what[ 1 ].second ;
  }
  std::cout << "The following name elements were found in the xml string:\n" ;
  std::copy( names.begin( ) , names.end( ) , std::ostream_iterator<std::string>( std::cout , "\n" )) ;
  return 0 ;

}</lang>

ColdFusion

<lang cfm><cfsavecontent variable="xmlString"> <inventory ... </inventory> </cfsavecontent> <cfset xml = xmlParse(xmlString)> <cfset itemSearch = xmlSearch(xml, "//item")> <cfset item = itemSearch[1]> <cfset priceSearch = xmlSearch(xml, "//price")> <cfloop from="1" to="#arrayLen(priceSearch)#" index="i">

 #priceSearch[i].xmlText#

</cfloop> <cfset names = xmlSearch(xml, "//name")> <cfdump var="#variables#"></lang>

D

It is important to note that the KXML library currently only supports XPath minimally.

Library: KXML

<lang d>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");

}</lang>

Groovy

<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</lang>

Haskell

<lang haskell>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</lang>

JavaScript

Works with: Firefox version 2.0

<lang javascript>//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 );</lang>

Although some browsers support XPath, working with XML is much easier with E4X.

<lang javascript>//create XML object from file var xhr = new XMLHttpRequest(); xhr.open('GET', 'file.xml', false); xhr.send(null); var doc = new XML(xhr.responseText);

//get first <item> element var firstItem = doc..item[0]; alert( firstItem );

//output contents of <price> elements for each( var price in doc..price ) {

 alert( price );

}

//add <name> elements to array var names = []; for each( var name in doc..name ) {

 names.push( name );

} alert( names );</lang>

Perl

<lang perl>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;</lang>

PHP

<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>'); //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; 

}</lang>

Python

<lang python># Python has basic xml parsing built in

from xml.dom import minidom

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

  1. 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

  1. 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

  1. 3rd Task: Get an array of all the "name" elements

namesArray = xmldoc.getElementsByTagName("name")</lang>

R

Library: XML (R)

<lang R>## Require the XML package you can download from http://www.omegahat.org/RSXML/ library("XML") doc <- xmlInternalTreeParse("test3.xml")

  1. 1st Task: Retrieve the first "item" element

(firstItemElement <- getNodeSet(doc, "//item")1)

  1. 2nd task: Perform an action on each "price" element (print it out)

prices <- sapply(getNodeSet(doc, "//price"), xmlValue) for(i in 1:length(prices)) print(prices[i])

  1. 3rd Task: Get an array of all the "name" elements

(namesArray <- sapply(getNodeSet(doc, "//name"), xmlValue))</lang>

Ruby

Library: REXML

<lang ruby>#Example taken from the REXML tutorial (http://www.germane-software.com/software/rexml/docs/tutorial.html) require "rexml/document" include REXML

  1. create the REXML Document from the string (%q is Ruby's multiline string, everything between the two @-characters is the string)

doc = Document.new(

       %q@<inventory title="OmniCorp Store #45x10^3">
            ...
          </inventory>
         @
                         )
  1. The invisibility cream is the first <item>

invisibility = XPath.first( doc, "//item" )

  1. Prints out all of the prices

XPath.each( doc, "//price") { |element| puts element.text }

  1. Gets an array of all of the "name" elements in the document.

names = XPath.match( doc, "//name" )</lang>

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 commands are being inputted into Scala's REPL, to better show the results.

<lang scala>scala> 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>

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" head firstItem: scala.xml.Node = <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 4.95 3.56

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

scala> val values = xml \\ "name" map (_ text) toArray values: Array[String] = Array(Invisibility Cream, Levitation Salve, Blork and Freen Instameal, Grob winglets)</lang>

Tcl

Library: tDOM

<lang tcl># 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]

}</lang>

Visual Basic .NET

<lang vbnet>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</lang>


XQuery

<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.
 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></lang>

Performing this XQuery on the given input document results in <lang xquery><?xml version="1.0" encoding="UTF-8"?> <result>

  <firstItem>
     <item upc="123456789" stock="12">
        <name>Invisibility Cream</name>
        <price>14.50</price>
        <description>Makes you invisible</description>
     </item>
  </firstItem>
  <prices>14.50 23.99 4.95 3.56</prices>
  <names>
     <name>Invisibility Cream</name>
     <name>Levitation Salve</name>
     <name>Blork and Freen Instameal</name>
     <name>Grob winglets</name>
  </names>

</result></lang>

XSLT

<lang xml><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:output method="text" />
 <xsl:template match="/">
 
   <xsl:text>

The first item element is</xsl:text>

   <xsl:value-of select="//item[1]" />
   
   <xsl:text>

The prices are: </xsl:text>

   <xsl:for-each select="//price">
     <xsl:text>
     </xsl:text>
     <xsl:copy-of select="." />
   </xsl:for-each>
   
   <xsl:text>

The names are: </xsl:text>

   <xsl:copy-of select="//name" />
 </xsl:template>  

</xsl:stylesheet></lang>