Consider this simple XML document. The serialized XML shown here is the result of an XmlSerializer from a complex POCO object whose schema I have no control over.
<My_RootNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns=""> <id root="2.16.840.1.113883.3.51.1.1.1" extension="someIdentifier" xmlns="urn:hl7-org:v3" /> <creationTime xsi:nil="true" xmlns="urn:hl7-org:v3" /> </My_RootNode>
The goal is to extract the value of the extension attribute on the id node. In this case, we are using the SelectSingleNode method, and given an XPath expression as such:
XmlNode idNode = myXmlDoc.SelectSingleNode("/My_RootNode/id"); //idNode is evaluated to null at this point in the debugger! string msgID = idNode.Attributes.GetNamedItem("extension").Value;
The problem is that the SelectSingleNode
method returns null for the given XPath expression.
Question: any ideas on this XPath query's correctness, or why this method call + XPath expression would return a null value? Perhaps the namespaces are part of the problem?
SelectSingleNode(String) Selects the first XmlNode that matches the XPath expression. SelectSingleNode(String, XmlNamespaceManager) Selects the first XmlNode that matches the XPath expression. Any prefixes found in the XPath expression are resolved using the supplied XmlNamespaceManager.
XPath return valuesa float, when the XPath expression has a numeric result (integer or float) a 'smart' string (as described below), when the XPath expression has a string result. a list of items, when the XPath expression has a list as result.
XPath Standard Functions Today XPath expressions can also be used in JavaScript, Java, XML Schema, PHP, Python, C and C++, and lots of other languages.
XPath (XML Path Language) is based on a DOM representation of an XML document. Therefore, you can use XPath to find a specific node or nodes in an XML file that match some criteria defined in the XPath expression.
I strongly suspect the problem is to do with namespaces. Try getting rid of the namespace and you'll be fine - but obviously that won't help in your real case, where I'd assume the document is fixed.
I can't remember offhand how to specify a namespace in an XPath expression, but I'm sure that's the problem.
EDIT: Okay, I've remembered how to do it now. It's not terribly pleasant though - you need to create an XmlNamespaceManager
for it. Here's some sample code that works with your sample document:
using System; using System.Xml; public class Test { static void Main() { XmlDocument doc = new XmlDocument(); XmlNamespaceManager namespaces = new XmlNamespaceManager(doc.NameTable); namespaces.AddNamespace("ns", "urn:hl7-org:v3"); doc.Load("test.xml"); XmlNode idNode = doc.SelectSingleNode("/My_RootNode/ns:id", namespaces); string msgID = idNode.Attributes["extension"].Value; Console.WriteLine(msgID); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With