我确信我在这里错过了一些简单的东西,但我已经和它搏斗了几天。我希望有人可以指出我错过的东西。
我从外部源收到以下简化格式的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”以及也没有结果。
我不确定我在这里缺少什么。任何帮助表示赞赏。
答案 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>
元素之前,您需要挖掘一个级别。