Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the 'xmlns' attribute affect XPath Node lookup?

The following code works perfect. See XML file below.

XPathDocument xPathDoc = new XPathDocument(@"C:\Authors.xml");
XPathNavigator navigator = xPathDoc.CreateNavigator();
XPathNodeIterator iterator = navigator.Select("/Contacts/Author/FirstName");
iterator.MoveNext();
string firstName = iterator.Current.InnerXml;
Console.WriteLine(firstName);

The value of 'firstName' returns 'Joe' which is perfect. However, when I add this attibute xmlns="http://www.w3.org/1999/xhtml" to the '' tag, so that it looks as follows:

<Author xmlns="http://www.w3.org/1999/xhtml">

then the code does not return the correct value ('Joe') Why then the attribute xmlns="http://www.w3.org/1999/xhtml" affects the code above and what am I missing to return the correct value?

Any help will be greatly appreciated.

Here is the xml file:

<?xml version="1.0" encoding="UTF-8" ?> 
<Contacts>
<Author>
<FirstName>Joe</FirstName>
</Author>
<Teacher>
<FirstName>Larry</FirstName>
</Teacher>

<Painter>
<FirstName>Mary</FirstName>
</Painter>
</Contacts>
like image 360
Jay Avatar asked Jan 18 '11 19:01

Jay


People also ask

What is the purpose of xmlns attribute?

The xmlns attribute specifies the xml namespace for a document. Note: The xmlns attribute is required in XHTML, invalid in HTML 4.01, and optional in HTML5. Note: The HTML validator at http://w3.org does not complain when the xmlns attribute is missing in an XHTML document.

Why we use xmlns in XML?

One of the primary motivations for defining an XML namespace is to avoid naming conflicts when using and re-using multiple vocabularies. XML Schema is used to create a vocabulary for an XML instance, and uses namespaces heavily.

What is namespace node in XPath?

XPath queries are aware of namespaces in an XML document and can use namespace prefixes to qualify element and attribute names. Qualifying element and attribute names with a namespace prefix limits the nodes returned by an XPath query to only those nodes that belong to a specific namespace.


2 Answers

xmlns is namespace which is used to avoid conflict between tags of the xml. Scenario, when one app is using xml from multiple sources and same tagname exist in two or more xml files. Since probablity of such ambiguity is high, namespace is used to reduce it.

like image 193
hungryMind Avatar answered Oct 01 '22 02:10

hungryMind


Your XPath expression is looking for elements "Contacts", "Author" and "FirstName" without namespaces. It looks like the Author element (and any descendant elements which don't have a namespace declaration) do have namespaces, do your XPath expression doesn't match.

To fix it, you'll need to use an XmlNamespaceManager, associate a prefix with the namespace and include that namespace in your XPath expression. Frankly, it gets messy.

Is there any reason you can't use LINQ to XML instead? It makes it much simpler to deal with XML in general and namespaces in particular. I'm happy to come up with a LINQ to XML sample if you're able to use it.

EDIT: Here's some sample LINQ to XML:

XDocument doc = XDocument.Load("authors.xml");
XNamespace ns = "http://www.w3.org/1999/xhtml";
var query = doc.Root
               .Elements(ns + "Author")
               .Elements(ns + "FirstName");
foreach (var element in query)
{
    Console.WriteLine((string) element);
}
like image 27
Jon Skeet Avatar answered Oct 01 '22 03:10

Jon Skeet