在 C# 程序的某个地方,我需要从 xml 结构中获取属性值。我可以直接作为 XElement 访问这个 xml 结构,并有一个简单的 xpath 字符串来获取属性。但是,使用 XPathEvaluate 时,我大部分时间都会得到一个空数组。(是的,有时会返回该属性,但大多数情况下它不是...对于完全相同的 XElement 和 xpath 字符串...)但是,如果我首先将 xml 转换为字符串并将其重新解析为 XDocument,我会这样做总是取回属性。有人可以解释这种行为吗?(我正在使用 .NET 3.5)
主要返回空 IEnumerable 的代码:
string xpath = "/exampleRoot/exampleSection[@name='test']/@value";
XElement myXelement = RetrieveXElement();
((IEnumerable)myXElement.XPathEvaluate(xpath)).Cast<XAttribute>().FirstOrDefault().Value;
总是有效的代码(我得到我的属性值):
string xpath = "/exampleRoot/exampleSection[@name='test']/@value";
string myXml = RetrieveXElement().ToString();
XDocument xdoc = XDocument.Parse(myXml);
((IEnumerable)xdoc.XPathEvaluate(xpath)).Cast<XAttribute>().FirstOrDefault().Value;
使用测试 xml:
<exampleRoot>
<exampleSection name="test" value="2" />
<exampleSection name="test2" value="2" />
</exampleRoot>
根据与周围根相关的建议,我在测试程序中做了一些“干测试”,使用相同的 xml 结构(txtbxXml 和 txtbxXpath 表示上述 xml 和 xpath 表达式):
// 1. XDocument Trial:
((IEnumerable)XDocument.Parse(txtbxXml.Text).XPathEvaluate(txtbxXPath.Text)).Cast<XAttribute>().FirstOrDefault().Value.ToString();
// 2. XElement trial:
((IEnumerable)XElement.Parse(txtbxXml.Text).XPathEvaluate(txtbxXPath.Text)).Cast<XAttribute>().FirstOrDefault().Value.ToString();
// 3. XElement originating from other root:
((IEnumerable)(new XElement("otherRoot", XElement.Parse(txtbxXml.Text)).Element("exampleRoot")).XPathEvaluate(txtbxXPath.Text)).Cast<XAttribute>().FirstOrDefault().Value.ToString();
结果:案例 1 和 3 产生正确的结果,而案例 2 抛出 nullref 异常。如果案例 3 失败而案例 2 成功,那对我来说会很有意义,但现在我不明白......