13

私のXMLは次のようになります:

<?xml version=\"1.0\"?>
<itemSet>
       <Item>one</Item>
       <Item>two</Item>
       <Item>three</Item>
       .....maybe more Items here.
</itemSet>

個々のアイテムの一部は、存在する場合と存在しない場合があります。存在する場合、要素<Item>2</Item>を取得したいとします。次の XPath を試しました (C# で)。

  • XMLNode node = myXMLdoc.SelectSingleNode("/itemSet[Item='two']")--- Item twoが存在する場合、最初の要素oneのみが返されます。子として値 2 のアイテムがどこかにある場合、このクエリは itemSet の最初の要素を指すだけかもしれません。この解釈は正しいでしょうか?

だから私は試しました:

  • XMLNode node = myXMLdoc.SelectSingleNode("/itemSet[Item='two']/Item[1]")--- このクエリは、<Item>itemSet 内で value = 'two' を持つ最初の要素を返します。私は正しいですか?

これはまだ最初の要素oneのみを返します。私は何を間違っていますか?どちらの場合も、兄弟を使用して子ノードをトラバースしてtwoに到達できますが、それは私が見ているものではありません。また、two が存在しない場合、SelectSingleNode は null を返します。したがって、成功した戻りノードを取得しているという事実は、要素 2 の存在を示しているため、 boolean テストでtwoの存在を確認したい場合は、上記の XPath のいずれかで十分ですが、実際には次のように完全な要素が必要です<Item>two</Item>。私のリターンノード。

[ここでの最初の質問であり、Web プログラミングを扱うのは初めてなので、SO の過去の質問から、上記の XPath と関連する xml をその場で学びました。だから優しくして、私がばかだったり、コミュニティのルールを無視していたり​​したら教えてください。ありがとう。]

4

1 に答える 1

23

私はあなたが欲しいと思います:

myXMLdoc.SelectSingleNode("/itemSet/Item[text()='two']")

つまり、 2 のテキストを含むアイテムではなく、2 のテキストを含むアイテムitemSetが必要です。

あなたの場合、単一のドットを使用してコンテキスト ノードを示すこともできます。

myXMLdoc.SelectSingleNode("/itemSet/Item[.='two']")

編集: と の違いは、.「このノード」を効果的に意味し、「このノードのすべてのテキスト ノードの子」を意味することです。どちらの場合も、比較は LHS の「文字列値」に対して行われます。要素ノードの場合、文字列値は「要素ノードのすべてのテキスト ノードの子孫の文字列値を文書順に連結したもの」であり、テキスト ノードのコレクションの場合、比較では、いずれかのテキスト ノードが等しいかどうかがチェックされます。あなたがテストしているもの。text().text()

したがって、要素のコンテンツにテキスト ノードが 1 つしかない場合は問題ではありませんが、次の場合を考えてみましょう。

<root>
  <item name="first">x<foo/>y</item>
  <item name="second">xy<foo/>ab</item>
</root>

次に、" " の XPath 式はroot/item[.='xy']最初の項目に一致しますが、" root/item[text()='xy']" は 2 番目の項目に一致します。

于 2009-05-19T16:17:25.140 に答える