XPath contains(text(),'some string') は、複数の Text サブノードを持つノードで使用すると機能しません。質問する

XPath contains(text(),'some string') は、複数の Text サブノードを持つノードで使用すると機能しません。質問する

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')]

これを詳しく説明すると、

  1. *任意の要素 (つまりタグ) に一致するセレクターであり、ノードセットを返します。
  2. これらは[]、そのノード セット内の個々のノードに対して動作する条件です。動作対象の個々のノードのいずれかが括弧内の条件に一致する場合、一致します。
  3. text()コンテキスト ノードの子であるすべてのテキスト ノードに一致するセレクターであり、ノード セットを返します。
  4. containsは文字列を操作する関数です。ノードセットが渡された場合、ノードセットは文書順で最初のノードセットのノードの文字列値を返すことによって文字列に変換されます。<Comment>したがって、要素の最初のテキスト ノード、つまり にのみ一致します。これは一致しないため、結果には はBLAH BLAH BLAH表示されません。<Comment>

これを変更する必要があります

//*[text()[contains(.,'ABC')]]
  1. *任意の要素 (つまりタグ) に一致するセレクターであり、ノードセットを返します。
  2. 外側は[]、そのノード セット内の個々のノードに対して動作する条件です。ここでは、ドキュメント内の各要素に対して動作します。
  3. text()コンテキスト ノードの子であるすべてのテキスト ノードに一致するセレクターであり、ノード セットを返します。
  4. 内側は[]、そのノード セット内の各ノード (ここでは各個別のテキスト ノード) に作用する条件です。各個別のテキスト ノードは、括弧内のパスの開始点であり、.括弧内として明示的に参照することもできます。作用する個別のノードのいずれかが括弧内の条件に一致する場合、一致します。
  5. containsは文字列を操作する関数です。ここでは、個別のテキスト ノード ( .) が渡されます。タグ内の 2 番目のテキスト ノードが<Comment>個別に渡されるため、文字列が認識され'ABC'、一致させることができます。

おすすめ記事