XML/XPath: Difference between revisions

From Rosetta Code
< XML
Content added Content deleted
Line 86: Line 86:
==[[C#]]==
==[[C#]]==
XmlReader XReader;
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>"));

Revision as of 10:05, 23 January 2007

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>

Ruby

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

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

C#

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