Thursday, 18 December 2008

Reading XML file in C# using XPath expressions

An example how to read XML file using XPath expression to access elements and attributes. Sample XML file

<?xml version="1.0" encoding="utf-8"?>
<bookstore>
    <book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
        <title1>The Autobiography of Benjamin Franklin</title1>
        <author>
            <first-name>Benjamin</first-name>
            <last-name>Franklin</last-name>
        </author>
        <price>8.99</price>
    </book>
    <book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
        <title1>The Confidence Man</title1>
        <author>
            <first-name>Herman</first-name>
            <last-name>Melville</last-name>
        </author>
        <price>11.99</price>
    </book>
</bookstore>

Reader code

XPathDocument doc = new XPathDocument(@"c:\temp\books.xml");
XPathNavigator nav = doc.CreateNavigator();
XPathNodeIterator nodeIterator = nav.Select("/bookstore/book");
foreach (XPathNavigator node in nodeIterator)
{
    Console.WriteLine(node.Name + ": " + node.GetAttribute("genre", ""));
    foreach (XPathNavigator subNode in node.Select("author"))
    {
        Console.WriteLine("  "+subNode.Name);
    }
}

There is an interesting problem when you have namespace defined as below, the code above doesn't like it.

<?xml version="1.0" encoding="utf-8"?>
<bookstore xmlns="http://www.contoso.com/books">
    <book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
    ...

In this situation you need to use XmlNamespaceManager to define a namespace prefix (can be anything) and then use it in your XPath expressions.

XPathDocument doc = new XPathDocument(@"c:\temp\books1.xml");
XPathNavigator nav = doc.CreateNavigator();
XmlNamespaceManager manager = new XmlNamespaceManager(nav.NameTable);         
manager.AddNamespace("ns", "http://www.contoso.com/books");
XPathNodeIterator nodeIterator = nav.Select("/ns:bookstore/ns:book", manager);
foreach (XPathNavigator node in nodeIterator)
{
    Console.WriteLine(node.Name + ": " + node.GetAttribute("genre", ""));
    foreach (XPathNavigator subNode in node.Select("ns:author",manager))
    {
        Console.WriteLine("  " + subNode.Name);
    }
}

No comments:

Post a Comment