XElement或XDocument上的XPathEvaluate之间有区别吗? [英] Difference between XPathEvaluate on XElement or XDocument?

查看:65
本文介绍了XElement或XDocument上的XPathEvaluate之间有区别吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#程序的某个地方,我需要从xml结构中获取属性值.我可以直接将它作为XElement到达xml结构,并具有一个简单的xpath字符串来获取属性.但是,使用XPathEvaluate,大多数时候我得到一个空数组.(是的,有时会返回该属性,但大多数情况下不是……对于完全相同的XElement和xpath字符串……)但是,如果我首先将xml转换为字符串并将其重新解析为XDocument,我总是会得到该属性.有人可以解释这种行为吗?(上午使用.NET 3.5)

Somewhere in a C# program, I need to get an attribute value from an xml structure. I can reach this xml structure directly as an XElement and have a simple xpath string to get the attribute. However, using XPathEvaluate, I get an empty array most of the time. (Yes, sometimes, the attribute is returned, but mostly it isn't... for the exact same XElement and xpath string...) However, if I first convert the xml to string and reparse it as an XDocument, I do always get the attribute back. Can somebody explain this behavior ? (Am using .NET 3.5)

通常返回一个空IEnumerable的代码:

Code that mostly returns an empty IEnumerable:

string xpath = "/exampleRoot/exampleSection[@name='test']/@value";
XElement myXelement = RetrieveXElement();
((IEnumerable)myXElement.XPathEvaluate(xpath)).Cast<XAttribute>().FirstOrDefault().Value;

始终有效的代码(我得到了我的属性值):

Code that does always work (I get my attribute 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结构(表示上述xml和xpath表达式的txtbxXml和txtbxXpath)进行了一些干式测试":

By suggestion related to a surrounding root, I did some 'dry tests' in a test program, using the same xml structure (txtbxXml and txtbxXpath representing the xml and xpath expression described above):

// 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成功了,那对我来说就有些道理了,但是现在我不明白了...

Result : case 1 and 3 produce the correct result, while case 2 throws a nullref exception. If case 3 would fail and case 2 succeed, it would have made some sense to me, but now I don't get it...

推荐答案

问题是XPath表达式以指定节点的子代开头.如果以 XDocument 开头,则根元素是子节点.如果从表示 exampleRoot 节点的 XElement 开始,则子级是两个 exampleSection 节点.

The problem is that the XPath expression is starting with the children of the specified node. If you start with an XDocument, the root element is the child node. If you start with an XElement representing your exampleRoot node, then the children are the two exampleSection nodes.

如果您将XPath表达式更改为"/exampleSection [@ name ='test']/@ value" ,它将从元素开始工作.如果将其更改为"//exampleSection [@ name ='test']/@ value" ,它将在 XElement XDocument .

If you change your XPath expression to "/exampleSection[@name='test']/@value", it will work from the element. If you change it to "//exampleSection[@name='test']/@value", it will work from both the XElement and the XDocument.

这篇关于XElement或XDocument上的XPathEvaluate之间有区别吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆