3

C# プログラムのどこかで、xml 構造から属性値を取得する必要があります。この xml 構造に XElement として直接到達し、単純な 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 構造 (上記の xml および xpath 式を表す txtbxXml および txtbxXpath) を使用して、テスト プログラムでいくつかの「ドライ テスト」を実行しました。

// 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();

Result : ケース 1 と 3 は正しい結果を生成しますが、ケース 2 は nullref 例外をスローします。ケース 3 が失敗し、ケース 2 が成功した場合、それは私には意味がありましたが、今では理解できません...

4

1 に答える 1

9

問題は、XPath 式が指定されたノードの子から始まっていることです。で始まる場合XDocument、ルート要素は子ノードです。XElementノードを表すから始めるとexampleRoot、子は 2 つのexampleSectionノードになります。

XPath 式を に変更する"/exampleSection[@name='test']/@value"と、要素から機能します。に変更すると、と の"//exampleSection[@name='test']/@value"両方から機能します。XElementXDocument

于 2012-11-26T14:09:24.137 に答える