C # XPath help - expression doesn't work

Here is an example XML document that matches the one with which I am getting the information:

<?xml version="1.0" standalone="yes"?> <Products xmlns="http://tempuri.org/Products.xsd"> <Movies> <Title>Title1</Title> <Language>English</Language> </Movies> <Movies> <Title>Title2</Title> <Language>English</Language> </Movies> <Movies> <Title>Title3</Title> <Language>French</Language> </Movies> <Books> <Title>BTitle1</Title> <Genre>Suspense</Genre> </Books> <Books> <Title>BTitle2</Title> <Genre>Suspense</Genre> </Books> <Books> <Title>BTitle3</Title> <Genre>SciFi</Genre> </Books> <Books> <Title>BTitle4</Title> <Genre>SciFi</Genre> </Books> </Products> 

Here is my code to get all the Suspense books:

 //Get state list using XPath XPathDocument xDoc = new XPathDocument(xmlPath); //Path to my file XPathNavigator xNav = xDoc.CreateNavigator(); string booksQuery = "Books[Genre = \"Suspense\"]"; XPathNodeIterator xIter = xNav.Select(booksQuery); while (xIter.MoveNext()) { //do stuff with xIter.Current } 

I tried several queries, including Products/Books[Genre = \"Suspense\"] , Products/Books , ./Books and Books . My xIter always has null elements.

I am new to XPath, so I'm sure this is a really simple mistake, but maybe not. I know that I can get a DataSet with tables [Films] and [Books] from this XML file using myDataSet.ReadXml(myXmlPathString); so that the XML file is not corrupted. If it helps anyone.

So my question is ... what am I doing wrong?

+6
c # xml xpath
source share
4 answers
 XPathDocument xDoc = new XPathDocument(xmlPath); //Path to my file XPathNavigator xNav = xDoc.CreateNavigator(); XmlNamespaceManager mngr = new XmlNamespaceManager(xNav.NameTable); mngr.AddNamespace("p", "http://tempuri.org/Products.xsd"); string booksQuery = "//p:Books[p:Genre = \"Suspense\"]"; XPathNodeIterator xIter = xNav.Select(booksQuery,mngr); 
+10
source share

You are looking for an element called Books that is not in the namespace. The Products element sets the default namespace for this element and all its descendants. You will need to use the namespace in XPath ... or use a different approach for queries, such as LINQ to XML. (Personally, I find LINQ to XML much easier to deal with XPath - especially when you need to get a namespace.)

+6
source share

As John said, you are missing a namespace.

You can do it in C # as follows

 //Get state list using XPath XPathDocument xDoc = new XPathDocument(xmlPath); //Path to my file XPathNavigator xNav = xDoc.CreateNavigator(); XmlNamespaceManager xmlns = new XmlNamespaceManager(xNav.NameTable); xmlns.AddNamespace("p", "http://tempuri.org/Products.xsd"); string booksQuery = "//p:Books[p:Genre = 'Suspense']"; XPathNodeIterator xIter = xNav.Select(booksQuery, xmlns); while (xIter.MoveNext()) { //do stuff with xIter.Current } 
+2
source share

With VTD-XML, the namespace is much simpler ... you can choose whether to ignore the namespace or not.

 VTDGen vg = new VTDGen(); if(vg.parseFile("product.xml",true)){ VTDNav vn = vg.getNav(); AutoPilot ap = new AutoPilot(vn); ap.selectXPath("Produt[Genre='suspence']"); int i = -1; while ((i = ap.evalXPath()) != -1) { // processing logic } } 
0
source share

All Articles