2016-04-08 10 views
1

System.Xml.XmlDocumentを超えるXPathで、隣接するテキストおよびCDataノードが見つからないのはなぜですか?System.Xml.XmlDocument上のXPathが隣接するテキストおよびCDataノードを検出しないのはなぜですか?

var raw_xml = @" 
<root> 
    <test> 
     <![CDATA[This is a CDATA node]]>And this is an adjacent text node 
    </test> 
</root> 
"; 

var doc = new XmlDocument(); 
doc.LoadXml(raw_xml); 

var results = doc.SelectNodes("/root/test/text()"); 
Console.WriteLine(results.Count); // gives: 1 
Console.WriteLine(results[0].Value); // gives: This is a CDATA node 
Console.WriteLine(results[0].Name); // gives: #cdata-section 
Console.WriteLine(results[0].GetType().FullName); // gives: System.Xml.XmlCDataSection 
Console.WriteLine(results[0].NextSibling.Name); // gives: #text 
Console.WriteLine(results[0].NextSibling.Value.Trim()); // gives: And this is an adjacent text node 

我々は、それが次の兄弟ですので、あなたが表現/root/test/text()がそれを見つけるだろうと思うだろうとしてCDATAノードがテキストノードを持っていることを上から見ることができます。 XPathので

同じ結果は:/root/test/node()

+0

「System.Xml.XmlDocument上のXPathが隣接するテキストおよびCDataノードを見つけられないのはなぜですか?」という問題を全体の問題として変更することを検討してください。答えは.NETフレームワークのDOM実装に固有であり、 "上記から、CDATAノードには次の兄弟のようにテキストノードがあることがわかります。したがって、/ root/test/text()式はXPATAデータモデルではCDATAを知らないノード。 –

+0

@マーティン、良い点 - ありがとう。私はOPを更新しました:) –

答えて

2

XML文書を扱う、あなたはおそらくCDATAノードがテキストノードに分離されているドキュメントオブジェクトモデル(DOM)に使用されています。 XPathデータモデルでは、隣り合うすべてのCDATAノードとテキストDOMノードの兄弟として一緒にノードtext()が見えます。

したがって、例えば、失敗します隣接シリーズの最初ではない、特定のDOMテキスト/ CDATAノードますクエリ作成しようと:確かに

var results = doc.SelectNodes("/root/test/text()[starts-with(., 'And')]"); 
Console.WriteLine(results.Count); // gives: 0 

とは、「選択しようとしているがテキストは、」他のXPathによるDOMノードを意味します

var results = doc.SelectNodes("/root/test/text()[contains(., 'text node')]"); 

はOPで初期/root/test/text()クエリと同じ結果が得られます。

あなたが見ているのは、2つのモデルが混在しています。つまり、XPathクエリの結果はDOMノードに戻されます。最初のtext()ノードを提供します。この場合、CDATAノードです。

あなたが本当にのXPathでの個別のテキストやCDATAノードで作業する必要がある場合、あなたはこのように、XMLコメントは、ソースドキュメント内のノードを分離していることを確認する必要がありますので

その

<root> 
    <test> 
     <![CDATA[This is a CDATA node]]><!-- separator comment -->And this is an adjacent text node 
    </test> 
</root> 

var results = doc.SelectNodes("/root/test/text()"); 
Console.WriteLine(results.Count); 

は、2となります。

関連する問題