SelectSingleNode and namespace - can't find nodes (using namespace mgr)
I have a relativly complex 开发者_JAVA技巧xml message I am recieving from a partner company. I need to parse up the xml to use it. I had it working fine, then they changed the message all around and now none of my SelectSingleNode commands work.
Structure of the message. Note the CDATA object with an embedded xml document. Not sure this matters or not. I was able to tweeze out the dataContent object, so it shouldn't make a difference. Here is what I am loading into the XmlDocument:
<ns5:dataContent xmlns:ns2="http://test/common/v1"
xmlns="http://test/schema/common"
xmlns:ns4="http://test/credentialing/stuff/v1"
xmlns:ns3="http://test/schema/ims/common/v1"
xmlns:ns5="http://test/schema/v1">
<createdBy>Micky</createdBy>
<createdAt>2011-03-08T17:00:27.050-05:00</createdAt>
<ns5:Id>39</ns5:Id>
<ns5:Type>4</ns5:Type>
-- lots more data --
</ns5:dataContent>
my code is fairly straight forward
var xmlDoc = new XmlDocument();
xmlDoc.Load(new StringReader(CDATA content));
var xmlNsM = new XmlNamespaceManager(xmlData.NameTable);
xmlNsM.AddNamespace(String.Empty, @"http://test/schema/common\");
xmlNsM.AddNamespace("ns5", @"http://test/schema/v1\");
xmlNsM.AddNamespace("m", @"http://test/message/v1\");
//This works
var order = xmlDoc.ChildNodes[0];
//This returns null
var ID = order.SelectSingleNode("ns5:Id", xmlNsM);
I can see that xmlDoc is being loaded properly. I have tried adding all 6 namespaces to the xmlNsM, but get the same results. None of my SelectSingleNodes works now.
Every post I have found on this subject says to just use the namespace manager, but I already knew that so its not been a very productive afternoon.
Just reading the code I think you are using the Namespace Manager correctly. Your problem is the XPath query. "ns5:Id" is not a child of the high level document and ChildNodes will only return one level down. You need to be searching decedents. Try:
var root = doc.DocumentElement;
var ID = root.SelectSingleNode("//ns5:Id", xmlNsM);
This isn't the most efficient because it will find all matches in the entire document. Take a look at some of the examples here: http://msdn.microsoft.com/en-us/library/ms256086.aspx
Well as is typically the case after hours and hours of looking at the problem, the solution was simple. The namespaces I added to the NSManager had a forward slash in front of the closing quotation mark ("http://test/schema/v1\"). Of course this is a delimiter, but since I just copied and pasted the namespace from the raw xml it was included. Once I removed them, I started finding all the fields I needed in the ns5 namespace.
I can't see the elements that don't have namespaces for some reason, but since I don't need those fields ATM, I'll figure that out later.
@ErnieL answer looks good (+1). There might also bee a problem is with
xmlNsM.AddNamespace(String.Empty, @"http://test/schema/common\");
because xpath does not like defaultnamespaces :-(. If @ErnieL answer still doesnot work change it to
xmlNsM.AddNamespace("default", @"http://test/schema/common\");
精彩评论