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 が成功した場合、それは私には意味がありましたが、今では理解できません...