考虑这个简单的XML文档.这里显示的序列化XML是来自复杂POCO对象的XmlSerializer的结果,该对象的模式我无法控制.
目标是在id节点上提取扩展属性的值.在这种情况下,我们使用SelectSingleNode方法,并给出一个XPath表达式:
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;
问题是该SelectSingleNode
方法为给定的XPath表达式返回null.
问题:关于此XPath查询的正确性的任何想法,或者为什么此方法调用+ XPath表达式将返回空值?也许命名空间是问题的一部分?
我强烈怀疑问题与名称空间有关.尝试摆脱命名空间,你会没事的 - 但显然这对你的实际案例没有帮助,我认为这个文件是固定的.
我不记得如何在XPath表达式中指定命名空间,但我确信这是问题所在.
编辑:好的,我记得现在该怎么做.虽然它不是非常令人愉快 - 你需要XmlNamespaceManager
为它创造一个.以下是一些适用于示例文档的示例代码:
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); } }
如果要完全忽略名称空间,可以使用:
static void Main(string[] args) { string xml = "\n" + " "; XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); XmlNode idNode = doc.SelectSingleNode("/*[local-name()='My_RootNode']/*[local-name()='id']"); }\n" + " \n" + "
这应该适用于你的情况而不删除命名空间:
XmlNode idNode = myXmlDoc.GetElementsByTagName("id")[0];
对不起,您忘记了命名空间.你需要:
XmlNamespaceManager ns = new XmlNamespaceManager(myXmlDoc.NameTable); ns.AddNamespace("hl7","urn:hl7-org:v3"); XmlNode idNode = myXmlDoc.SelectSingleNode("/My_RootNode/hl7:id", ns);
实际上,无论是在此处还是在Web服务中,从XPath操作或依赖于XPath的任何操作返回null通常都表明XML命名空间存在问题.