【问题标题】:Why my XPath request to XML file on web doesn't work?为什么我对 Web 上的 XML 文件的 XPath 请求不起作用?
【发布时间】:2009-11-26 19:21:54
【问题描述】:

有一个带有汇率http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml的XML文件:

<gesmes:Envelope>
  <gesmes:subject>Reference rates</gesmes:subject>
  <gesmes:Sender>
    <gesmes:name>European Central Bank</gesmes:name>
  </gesmes:Sender>
  <Cube>
    <Cube time="2009-11-26">
      <Cube currency="USD" rate="1.5071"/>
       ...

我执行下一个 XPath 请求:

var doc = new XmlDocument();
doc.Load(url);
var node = doc.SelectSingleNode("//Cube[@currency=\"USD\""]);
var value = node.Attributes["rate"].Value;

但它返回null!我的错在哪里?

如果我提出这个要求,一切正常:

var node = dic.SelectSingleNode("//*[@currency=\"USD\"]");
var name = node.Name; // "Cube"

【问题讨论】:

    标签: c# .net xml web-services xpath


    【解决方案1】:

    问题在于命名空间。如果您可以使用 LINQ to XML,则可以很容易地表达此查询。否则,它会有点棘手 - 你会想要这样的东西:

    var doc = new XmlDocument();
    doc.Load(url);
    XPathNavigator navigator = doc.CreateNavigator();    
    XmlNamespaceManager nsMgr = new XmlNamespaceManager(nav.NameTable);
    nsMgr.AddNamespace("gesmes", "http://www.gesmes.org/xml/2002-08-01");
    nsMgr.AddNamespace("ns0", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref");
    
    var node = doc.SelectSingleNode("//ns0:Cube[@currency=\"USD\""], nsMgr);
    var value = node.Attributes["rate"].Value;
    

    (您并不真正需要管理器中的 gesmes 命名空间,但如果您需要查找任何其他元素,它会更容易。)

    编辑:Peter Murray-Rust 的回答在这里是一个不错的选择 - 您采用哪种方法取决于您希望能够找到元素的具体程度。如果您只需要一个查询的名称空间,那么将 URI 直接包含在 XPath 中是有意义的;如果您需要它的用途不止于此,您将使用命名空间管理器获得更简洁的查询。

    【讨论】:

      【解决方案2】:

      试试

      var node = doc.SelectSingleNode("//*[local-name()='Cube' and @currency=\"USD\""]);
      

      如果你知道的话,你可以随时添加到命名空间中

      var node = doc.SelectSingleNode("//*[local-name()='Cube' and 
           namespace-uri()='http://www.ecb.int/vocabulary/2002-08-01/eurofxref' and
           @currency=\"USD\""]);
      

      虽然它很冗长,但我更喜欢尝试整理命名空间前缀。而且也避免了默认命名空间(xmlns="")的问题

      【讨论】:

      • 谢谢!有用!顺便说一句,我认为在 XPath 中引用相同的符号会更好:quotes " or apostrophe '
      • 好 - 我通常会使用 '...' 但保留在您的引号中,以免混淆读者。就我个人而言,我发现 \" 因为我使用 Java 并且反斜杠倍增得很快
      【解决方案3】:

      XPathVisualizer 可以很方便。免费。它不会告诉你使用命名空间,但它会在 UI 中将命名空间放在你面前,它会让你测试一堆替代方案,非常快。

      【讨论】:

        猜你喜欢
        • 2017-01-17
        • 1970-01-01
        • 1970-01-01
        • 2012-02-13
        • 1970-01-01
        • 2020-11-28
        • 1970-01-01
        • 1970-01-01
        • 2021-05-14
        相关资源
        最近更新 更多