无法获取XmlDocument.SelectNodes来检索我的任何节点?
我正在尝试解析XML文档。 有问题的文档是AppxManifest文件。
示例文档如下所示:
jhjj bhhjb Assets\StoreLogo.png 6.2.1 6.2.1 Text
我尝试像这样解析它:
var xml=new XmlDocument(); xml.Load(myfile); var mgr=new XmlNamespaceManager(xml.NameTable); mgr.AddNamespace("", "http://schemas.microsoft.com/appx/2010/manifest"); var nodes=xml.SelectNodes("Applications");
但是,执行此操作后, nodes
将永远不会包含任何内容。 虽然加载了xml文档。 使用SelectNodes("//*")
按预期返回每个节点。 我的问题在这里是什么?
我也尝试过很多关于XPath查询的变体,例如
-
/Package/Applications/Application
-
Applications/Application
-
Applications/*
但是,似乎没有任何东西可以检索单个节点。 理想情况下,我希望节点包含所有Application
节点
您必须专门使用xml命名空间来选择它们。 考虑
"//*[local-name()='Applications']/*[local-name()='Application']"
在您的情况下,此代码也可以正常工作:
var doc = new XmlDocument(); doc.LoadXml(xml); var nsmgr = new XmlNamespaceManager(doc.NameTable); nsmgr.AddNamespace("a", "http://schemas.microsoft.com/appx/2010/manifest"); var nodes = doc.SelectNodes("//a:Applications/a:Application",nsmgr);
您需要在NamespaceManager和XPath中为名称空间指定前缀。 请注意,除了XPath和命名空间管理器*之外,前缀不需要匹配任何内容。
var xml=new XmlDocument(); xml.Load(myfile); var mgr=new XmlNamespaceManager(xml.NameTable); mgr.AddNamespace("a", "http://schemas.microsoft.com/appx/2010/manifest"); mgr.AddNamespace("bar", "http://schemas.microsoft.com/developer/appx/2012/build"); var nodes=xml.SelectNodes("//a:Applications", mgr);
正如其他答案所指出的,接受任何命名空间的XPath是另一种选择。
*)即在您的特定示例中,有2个名称空间“default”(请注意,默认前缀与空名称空间不同)和“build”。 因此,当您定义命名空间管理器时,您需要为每个命名空间指定一个前缀(如果您需要在两者中都定位节点),但前缀可以是任意字符串(对前缀有效但不为空)。 即,对于“默认”命名空间使用“a”,对于映射到XML中的“build”的命名空间使用“bar”。
您可能需要阅读此内容
这是你的代码:
var xml = new XmlDocument(); xml.Load("myXMLFile1.xml"); var mgr = new XmlNamespaceManager(xml.NameTable); mgr.AddNamespace("", "http://schemas.microsoft.com/appx/2010/manifest"); XmlNode root = xml.DocumentElement; var nodes = root.SelectNodes("//*[local-name()='Applications']/*[local-name()='Application']");
不是在这种特殊情况下,但通常情况下,如果实际XML中的命名空间URN与用于向命名空间管理器添加命名空间的命名空间不完全相同(例如:缺少尾部斜杠),并且在XPath中指定了前缀,查询可能返回null
。
如果XML中的命名空间URN不可靠,则为语法
"//*[local-name()='tag']"
将工作。