Pages

Thursday 18 June 2009

XPath

XPath came handy lately as I needed to look-up an in-memory XML document.
I know it's probably smoother with Linq to Xml but my project had to compile under VS2005 so I used the .NET 2.0 library which does not contain Linq but contains XPath.

Starting from the following xml file:

<?xml version="1.0" encoding="utf-8"?>
<pigs>
  <piggy infected="false" name="bob"/>
  <piggy infected="false" name="alfred"/>
  <piggy infected="true" name ="rodrigo">
    <disease name="swine flu"/>
    <disease name="boredom"/>
    <disease name="pig blues"/>
    <address>confidential</address>
    <phonenumber>01234546576</phonenumber>
  </piggy>
</pigs>


To load the XML in memory:

XmlDocument doc = new XmlDocument();

try

{

doc.Load("piggy.xml");

}

catch (XmlException e)

{

Console.WriteLine("Could not load the file. Detail: " + e.Message);

}



To query elements based on their name:

XmlNodeList allPigs = doc.SelectNodes("/pigs/piggy"); // Returns all nodes called 'piggy' located inside the root-level node called 'pigs'.

foreach (XmlNode node in allPigs)

Console.WriteLine(node.Name + " " + node.Attributes["name"].Value);



To query elements based on their attribute name:

// Returns only infected pigs

XmlNodeList infectedPigs = doc.SelectNodes("/pigs/piggy[@infected='true']");

foreach (XmlNode node in infectedPigs)

Console.WriteLine(node.Name + " " + node.Attributes["name"].Value);


To return a single node (same query as above but only one node is expected):


// Returns the single infected pig

XmlNode infectedPig = doc.SelectSingleNode("/pigs/piggy[@infected='true']");

if (infectedPig != null)

Console.WriteLine(infectedPig.Name + " " + infectedPig.Attributes["name"].Value);


To do a query relative to the current node:
All queries above were made relative to the top of the document. But it you call SelectNodes against an XmlNode, you can do a query relative to that node. Just ommit the '/':

// Query relative to the current node. Returns all diseases for the infected pig

XmlNodeList diseases = infectedPig.SelectNodes("disease");

foreach (XmlNode node in diseases)

Console.WriteLine(node.Name + " " + node.Attributes["name"].Value);



Resources:
MSDN: XPath Syntax
LINQ to XML queries
XML Support in SQL Server 2005

No comments: