【问题标题】:C# and XPath - how to queryC# 和 XPath - 如何查询
【发布时间】:2010-11-14 17:54:10
【问题描述】:

我有一个 XML 文件,其结构如下:

<mediawiki ...>
  <siteinfo>...</siteinfo>
  <page>
    <title>The Title</title>
    <id>42</id>
    ...
  </page>
  ... more page items ...
</mediawiki>

我对 XPath-Query 有点红,写了如下代码:

_xmlArticlesDocument = new XmlDocument();
_xmlArticlesDocument.Load(xmlArticlesFileName);

现在我想掌握具有给定 id-Subelement 的页面元素。于是我写了:

XmlNode node = _xmlArticlesDocument.DocumentElement.SelectSingleNode
               ("//mediawiki/page[id=" + id.ToString() + "]");

但节点始终为空。我尝试了几个查询,包括“page/id”、“page”、“/page”、“//page”来获取任何东西,但节点始终为空。我通过快速检查检查了 _xmlArticlesDocument 变量,它包含具有预期结构的正确 XML 文件。

在我看来,我错过了一些非常基本的东西,但不知道是什么。也许这里有人有想法?

提前致谢, 弗兰克

【问题讨论】:

    标签: c# xpath


    【解决方案1】:

    查看 Linq to XML。我也是一个 XML 菜鸟,我发现它更简单,XMLDocument。

    【讨论】:

    • 我也打算这么建议。如果你还不知道 XPath 并且只需要它在 C#.Net 中通过 XML 解析,那么 Linq to XML 就是要走的路。
    • 我同意,如果您还没有 XPath,您可能会发现 LINQ 方法更好,因为这些技能更容易转移。
    • 啊,我认为这些是启动问题。将这些位放在一起后,对我来说它看起来非常直观。有了 StackOverflow 上这个很棒的社区,那些启动问题不会长期得不到解决;)
    【解决方案2】:

    根据您目前向我们展示的内容,查询看起来是正确的。但是我怀疑在 mediawiki 元素的“...”后面有一个 xmlns="...." 属性对吗?

    我怀疑这就是绊倒你的原因。您将需要这样的代码:-

     XmlNamespaceManager nsmgr = new XmlNamespaceManager(_xmlArticlesDocument.NameTable);
     nsmgr.AddNamespace("a", "the-namespace-in-them-xmlns-attribute");
     XmlNode page = _xmlArticlesDocument.SelectSingleNode(String.Format("//a:page[id={0}]", id), nsmgr);
    

    【讨论】:

    • 这是前进的道路,我遇到了很多麻烦,但一旦你掌握了这一点,就很容易了。 :)
    • 一针见血!问题是缺少命名空间管理器,我红色的教程中没有提到。但是需要对查询进行一些更改,因为 id-Element 也在命名空间中:“a:page[a:id=" + id.toString() + "]" 正确地完成了这项工作。非常感谢!
    【解决方案3】:

    你试过了吗:

    _xmlArticlesDocument.DocumentElement.SelectSingleNode
                   ("page[id='" + id.ToString() + "']"); // Note the single quotes
    

    此外,如果任何 XML 节点位于不是默认名称空间的命名空间中(即 &lt;mediawiki xmlns="whatever"&gt;),那么您还需要一个 XmlNamespaceManager

    【讨论】:

    • // 应该将查询移动到文档的开头。
    • 我没有建议使用 //... 还是我不明白你的意思?
    • 不要忘记确保/检查id 不包含单引号,否则SelectSingleNode() 将由于无效的XPath 而失败。
    • @Sean:抱歉,原始查询无论如何都应该有效(我假设您错过了问题中的 //)。
    • 单引号可以省略,正如我现在测试的那样。正如您所提到的,问题是缺少命名空间。
    猜你喜欢
    • 1970-01-01
    • 2018-08-14
    • 2010-10-03
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多