C#选择未找到节点的节点

时间:2018-05-15 18:34:47

标签: c# xml xpath

我确信我在这里错过了一些简单的东西,但我已经和它搏斗了几天。我希望有人可以指出我错过的东西。

我从外部源收到以下简化格式的XML消息:

<root>
  <A>
    <B xmlns="http://www.something.com/Document>
      <C>Value1</C> 
      <D>Value2</D>
      <E>Value3</E>
    </B>
  </A>
  <A>
    <B xmlns="http://www.something.com/Document>
      <D>Value5</D>
      <E>Value6</E>
    </B>
  </A>
</root>

我正试图拔出D元素。

我试过了:

XmlNodeList xmlResults = xdPayload.SelectNodes("//D")

这没有返回任何结果。然后认为名称空间是我试过的问题:

XmlNamespaceManager nsmgr = new XmlNamespaceManager(xdPayload.NameTable);
xnlResults = xdPayload.SelectNodes("//D", nsmgr);

再次没有结果。我不认为我需要添加默认命名空间,但是当思考智能不起作用时,请认为愚蠢。所以我尝试了这个:

XmlNamespaceManager nsmgr = new XmlNamespaceManager(xdPayload.NameTable);
nsmgr.AddNamespace("", "http://www.something.com/Document");
xnlResults = xdPayload.SelectNodes("//D", nsmgr);

仍然没有结果。我尝试了更多描述性的XPath,如“/ root / A / B / D”和“/root/A/B[@xmlns="http://www.somewhere.com/Document"]/D”以及也没有结果。

我不确定我在这里缺少什么。任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:1)

尝试添加以前缀命名的命名空间,然后将<D>称为ns0:D

NameTable nt = new NameTable();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);
nsmgr.AddNamespace("ns0", "http://www.something.com/Document");
xnlResults = xdPayload.SelectNodes("/root/A/ns0:B/ns0:D", nsmgr);

这应该选择<D>元素进行进一步处理。

如果这不起作用,您将始终可以选择忽略所有名称空间,例如

XmlNodeList xmlResults = xdPayload.SelectNodes("//*[local-name()='D']")

答案 1 :(得分:1)

使用XElement

string text = @"
    <root>
        <A>
        <B xmlns='http://www.something.com/Document'>
            <C>Value1</C> 
            <D>Value2</D>
            <E>Value3</E>
        </B>
        </A>
        <A>
        <B xmlns='http://www.something.com/Document'>
            <D>Value5</D>
            <E>Value6</E>
        </B>
        </A>
    </root>";

XNamespace ns = "http://www.something.com/Document";
var xml = XElement.Parse(text);
var ds = xml.Descendants(ns + "D");
ds.ToList().ForEach(Console.WriteLine);

答案 2 :(得分:1)

我在同样的问题上挣扎。关键是Descendants()方法。由于您拥有<root>元素,因此在开始引用<A><B>元素之前,您需要挖掘一个级别。