【问题标题】:Unable select XmlNode by Xpath with two attributes无法通过具有两个属性的 Xpath 选择 XmlNode
【发布时间】:2021-07-05 16:56:18
【问题描述】:

我有xml作为响应,需要找到标记的红色箭头节点:

我的代码:

 //response to xmlDocument
 document = new XmlDocument();
 document.LoadXml(response.Content);
 XmlNamespaceManager ns = new XmlNamespaceManager(document.NameTable);
 foreach (XmlAttribute curAttribute in document.DocumentElement.Attributes)
        {
          if (curAttribute.Prefix.Equals("xmlns"))
             { ns.AddNamespace(curAttribute.LocalName, curAttribute.Value); }
         }
            
 string xpath = "//edmx:Edmx/edmx:DataServices/Schema[@Namespace='Core.Entities']/EntityType[@Name='Office']/Property[@Name='OfficeKeyNumeric']";
            XmlNode node = document.SelectSingleNode(xpath, ns);
        }

我有一个错误,给定的 XPath 找不到节点,节点为空。

我尝试了什么:

and

string xpath = "//edmx:Edmx/edmx:DataServices/Schema[@Namespace='Core.Entities' and @xmlns='http://docs.oasis-open.org/odata/ns/edm']/EntityType[@Name='Office']/Property[@Name='OfficeKeyNumeric']";
        

没有and

string xpath = "//edmx:Edmx/edmx:DataServices/Schema[@Namespace='Core.Entities'][@xmlns='http://docs.oasis-open.org/odata/ns/edm']/EntityType[@Name='Office']/Property[@Name='OfficeKeyNumeric']";

也尝试使用管道 |& - 没有任何帮助。

为什么它不起作用,是否有可能让它以这种方式起作用?

我现在使用的唯一一个可行的解决方案是在加载之前从 XML 文档中删除 xmlns="http://docs.oasis-open.org/odata/ns/edm",之后我上面的代码就可以正常工作了。

document.LoadXml(response.Content.Replace("xmlns=\"http://docs.oasis-open.org/odata/ns/edm\"", ""));

【问题讨论】:

  • 您是否注意到Schema 元素也有自己的xmlns 属性?
  • 相当于<edm:Schema xmlns:edm="http://docs.oasis-open.org/odata/ns/edm">。这么想吧。
  • 是的,这是一个问题——如何在它下面找到一个节点?我目前正在从文档中删除该 xmlns 和相关链接,因为如果 Shema 有两个属性,则无法到达节点
  • 谢谢@madreflection 会试试的

标签: c# xmldocument xmlnode


【解决方案1】:

Schema 元素及其后代在 http://docs.oasis-open.org/odata/ns/edm 命名空间中声明,必须在 xpath 您正在寻找的声明。

string xpath = "//edmx:Edmx/edmx:DataServices/edm:Schema[@Namespace='Core.Entities']/edm:EntityType[@Name='Office']/edm:Property[@Name='OfficeKeyNumeric']";

确保使用这些命名空间初始化您的 XmlNamespaceManager

XmlNamespaceManager ns = new XmlNamespaceManager(document.NameTable);
ns.AddNamespace("edmx","http://docs.oasis-open.org/odata/ns/edmx");
ns.AddNamespace("edm","http://docs.oasis-open.org/odata/ns/edm");

【讨论】:

  • 根上的edmx 别名是针对以edmx 结尾的命名空间,但Schema 元素的命名空间不同;它没有x。它需要一个不同的前缀。
  • @madreflection 从图片中注销时错过了那个。谢谢!
  • 是的,看起来更像它。命名空间应该事先知道,前缀不需要与文件匹配,所以像这样显式构建XmlNamespaceManager 是有意义的。
  • @pfx 对不起图片,那个 xml 很大
  • @Lia:您不需要发布整个文件,就像屏幕截图中的一样多。请记住,帮助您的人可能想要复制/粘贴它,无论是自己测试某些东西还是将其包含在他们的答案中。这就是为什么我们要求所有代码和错误消息都是文本(屏幕截图只是补充)。
猜你喜欢
  • 1970-01-01
  • 2019-02-10
  • 2021-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多