XML/XPath

From Rosetta Code

< XML
Jump to: navigation, search
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">
  <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>

Contents

[edit] AutoHotkey

With regular expressions

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

Library: AHK XPath

#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")

[edit] 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);

[edit] C++

#include <vector>
#include <string>
#include <iostream>
#include <boost/regex.hpp>
#include <algorithm>
#include <iterator>
 
int main( ) {
const std::string xmltext(
"<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>" ) ;
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 ;
}

[edit] ColdFusion

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

[edit] Common Lisp

Library: plexippus-xpath Library: cxml Library: cxml-stp

(dolist (system '(:xpath :cxml-stp :cxml))
(asdf:oos 'asdf:load-op system))
 
(defparameter *doc* (cxml:parse-file "xml" (stp:make-builder)))
 
(xpath:first-node (xpath:evaluate "/inventory/section[1]/item[1]" *doc*))
 
(xpath:do-node-set (node (xpath:evaluate "/inventory/section/item/price/text()" *doc*))
(format t "~A~%" (stp:data node)))
 
(defun node-array (node-set)
(coerce (xpath:all-nodes node-set) 'vector))
 
(node-array
(xpath:evaluate "/inventory/section/item/name" *doc*))

[edit] D

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

import kxml.xml;
char[]xmlinput =
"<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>
"
;
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");
}

[edit] E

Library: E-XML (currently a very early work in progress/draft library; design comments welcome)

? def xml__quasiParser := <import:org.switchb.e.xml.makeXMLQuasiParser>()
> def xpath__quasiParser := xml__quasiParser.xPathQuasiParser()
> null
 
? def doc := xml`<inventory title="OmniCorp Store #45x10^3">
> <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>n>
> </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>`

# value: xml`...`
 
? doc[xpath`inventory/section/item`][0]
# value: xml`<item stock="12" upc="123456789">
# <name>Invisibility Cream</name>
# <price>14.50</price>
# <description>Makes you invisible</description>
# </item>`
 
? for price in doc[xpath`inventory/section/item/price/text()`] { println(price :String) }
14.50
23.99
4.95
3.56
 
? doc[xpath`inventory/section/item/name`]
# value: [xml`<name>Invisibility Cream</name>`,
# xml`<name>Levitation Salve</name>`,
# xml`<name>Blork and Freen Instameal</name>`,
# xml`<name>Grob winglets</name>`]
 

[edit] 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

[edit] 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

Using the Haskell XML Toolkit (HXT):

{-# LANGUAGE Arrows #-}
import Text.XML.HXT.Arrow
 
deepElem name = deep (isElem >>> hasName name)
 
process = proc doc -> do
item <- single (deepElem "item") -< doc
_ <- listA (arrIO print <<< deepElem "price") -< doc
names <- listA (deepElem "name") -< doc
returnA -< (item, names)
 
main = do
[(item, names)] <- runX (readDocument [] "xmlpath.xml" >>> process)
print item
print names

[edit] HicEst

CHARACTER xml*1000, output*1000
READ(ClipBoard) xml
 
EDIT(Text=xml, Right='<item', Right=5, GetPosition=a, Right='</item>', Left, GetPosition=z)
WRITE(Text=output) xml( a : z), $CRLF
 
i = 1
1 EDIT(Text=xml, SetPosition=i, SePaRators='<>', Right='<price>', Word=1, Parse=price, GetPosition=i, ERror=99)
IF(i > 0) THEN
WRITE(Text=output, APPend) 'Price element = ', price, $CRLF
GOTO 1 ! HicEst does not have a "WHILE"
ENDIF
 
EDIT(Text=xml, SPR='<>', R='<name>', W=1, WordEnd=$CR, APpendTo=output, DO=999)
WRITE(ClipBoard) TRIM(output)
 upc="123456789" stock="12">
<name>Invisibility Cream</name>
<price>14.50</price>
<description>Makes you invisible</description>
 
Price element = 14.50
Price element = 23.99
Price element = 4.95
Price element = 3.56
Invisibility Cream
Levitation Salve
Blork and Freen Instameal
Grob winglets
 

[edit] JavaScript

Works with: Firefox version 2.0

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

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

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

[edit] Oz

We implement a small subset of XPath for this task:

declare
[XMLParser] = {Module.link ['x-oz://system/xml/Parser.ozf']}
 
proc {Main Data}
Parser = {New XMLParser.parser init}
[Doc] = {Parser parseVS(Data $)}
 
FirstItem = {XPath Doc [inventory section item]}.1
 
Prices = {XPath Doc [inventory section item price Text]}
 
Names = {XPath Doc [inventory section item name]}
in
{ForAll Prices System.showInfo}
end
 
%%
%% Emulation of some XPath functionality:
%%
 
fun {XPath Doc Path}
P|Pr = Path
in
Doc.name = P %% assert
{FoldL Pr XPathStep [Doc]}
end
 
fun {XPathStep Elements P}
if {IsProcedure P} then
{Map Elements P}
else
{FilteredChildren Elements P}
end
end
 
%% A flat list of all Type-children of all Elements.
fun {FilteredChildren Elements Type}
{Flatten
{Map Elements
fun {$ E}
{Filter E.children
fun {$ X}
case X of element(name:!Type ...) then true
else false
end
end}
end}}
end
 
%% PCDATA of an element as a ByteString
fun {Text Element}
Texts = for Child in Element.children collect:C do
case Child of text(data:BS ...) then {C BS} end
end
in
{FoldR Texts ByteString.append {ByteString.make nil}}
end
 
Data =
"<inventory title=\"OmniCorp Store #45x10^3\">"
#" <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>"
in
{Main Data}

[edit] Perl

Library: XML::XPathXPath

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;

[edit] 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;
}

[edit] PicoLisp

(load "@lib/xm.l")
 
(let Sections (body (in "file.xml" (xml)))
(pretty (car (body (car Sections))))
(prinl)
(for S Sections
(for L (body S)
(prinl (car (body L 'price))) ) )
(make
(for S Sections
(for L (body S)
(link (car (body L 'name))) ) ) ) )

Output:

(item
   ((upc . "123456789") (stock . "12"))
   (name NIL "Invisibility Cream")
   (price NIL "14.50")
   (description NIL "Makes you invisible") )
14.50
23.99
4.95
3.56
-> ("Invisibility Cream" "Levitation Salve" "Blork and Freen Instameal" "Grob winglets")

[edit] 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
 
# 1st Task: Retrieve the first "item" element
i = xmldoc.getElementsByTagName("item") # get a list of all "item" tags
firstItemElement = i[0] # get the first element
 
# 2nd task: Perform an action on each "price" element (print it out)
for j in xmldoc.getElementsByTagName("price"): # get a list of all "price" tags
print j.childNodes[0].data # XML Element . TextNode . data of textnode
 
# 3rd Task: Get an array of all the "name" elements
namesArray = xmldoc.getElementsByTagName("name")

[edit] R

Library: XML (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
(firstItemElement <- getNodeSet(doc, "//item")[[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])
# 3rd Task: Get an array of all the "name" elements
(namesArray <- sapply(getNodeSet(doc, "//name"), xmlValue))

[edit] Ruby

Library: REXML

#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" )

[edit] 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.

scala> val 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>
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" 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)

[edit] Tcl

Library: tDOM

# 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]
}

[edit] Visual Basic .NET

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


[edit] 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>

Performing this XQuery on the given input document results in

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

[edit] XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="/">
 
<!-- 1. first item element -->
<xsl:text>
The first item element is</xsl:text>
<xsl:value-of select="//item[1]" />
 
<!-- 2. Print each price element -->
<xsl:text>
The prices are: </xsl:text>
<xsl:for-each select="//price">
<xsl:text>
</xsl:text>
<xsl:copy-of select="." />
</xsl:for-each>
 
<!-- 3. Collect all the name elements -->
<xsl:text>
The names are: </xsl:text>
<xsl:copy-of select="//name" />
</xsl:template>
</xsl:stylesheet>
Personal tools
Support