dom4j の XPath contains に関して小さな問題があります...
私のXMLが
<Home>
<Addr>
<Street>ABC</Street>
<Number>5</Number>
<Comment>BLAH BLAH BLAH <br/><br/>ABC</Comment>
</Addr>
</Home>
ルート要素を指定して、テキストに ABC が含まれるすべてのノードを検索するとします...
私が書く必要のあるXPathは次のようになります
//*[contains(text(),'ABC')]
Street
しかし、これは dom4j が返すものではありません...このクエリは要素のみを返し、要素は返さないので、これは dom4j の問題ですか、それとも XPath の動作の私の理解の問題ですかComment
?
DOMはComment
要素を4つのタグを持つ複合要素にします。
[Text = 'XYZ'][BR][BR][Text = 'ABC']
クエリは要素を見つけてそれに対して contains を実行する必要があるため、依然として要素を返すはずだと思いますが、そうではありません...
次のクエリは要素を返しますが、要素だけではなく、親要素も返します。これは問題にとって望ましくありません。
//*[contains(text(),'ABC')]
要素とだけを返す XPath クエリを知っている人はいます<Street/>
か<Comment/>
?
ベストアンサー1
タグ<Comment>
には 2 つのテキスト ノードと 2 つの子<br>
ノードが含まれています。
あなたのXPath式は
//*[contains(text(),'ABC')]
これを詳しく説明すると、
*
任意の要素 (つまりタグ) に一致するセレクターであり、ノードセットを返します。- これらは
[]
、そのノード セット内の個々のノードに対して動作する条件です。動作対象の個々のノードのいずれかが括弧内の条件に一致する場合、一致します。 text()
コンテキスト ノードの子であるすべてのテキスト ノードに一致するセレクターであり、ノード セットを返します。contains
は文字列を操作する関数です。ノードセットが渡された場合、ノードセットは文書順で最初のノードセットのノードの文字列値を返すことによって文字列に変換されます。<Comment>
したがって、要素の最初のテキスト ノード、つまり にのみ一致します。これは一致しないため、結果には はBLAH BLAH BLAH
表示されません。<Comment>
これを変更する必要があります
//*[text()[contains(.,'ABC')]]
*
任意の要素 (つまりタグ) に一致するセレクターであり、ノードセットを返します。- 外側は
[]
、そのノード セット内の個々のノードに対して動作する条件です。ここでは、ドキュメント内の各要素に対して動作します。 text()
コンテキスト ノードの子であるすべてのテキスト ノードに一致するセレクターであり、ノード セットを返します。- 内側は
[]
、そのノード セット内の各ノード (ここでは各個別のテキスト ノード) に作用する条件です。各個別のテキスト ノードは、括弧内のパスの開始点であり、.
括弧内として明示的に参照することもできます。作用する個別のノードのいずれかが括弧内の条件に一致する場合、一致します。 contains
は文字列を操作する関数です。ここでは、個別のテキスト ノード (.
) が渡されます。タグ内の 2 番目のテキスト ノードが<Comment>
個別に渡されるため、文字列が認識され'ABC'
、一致させることができます。