25

このようなマークアップを持つ:

<div class="foo">
   <div><span class="a1"></span><a href="...">...</a></div>
   <div><span class="a2"></span><a href="...">...</a></div>
   <div><span class="a1"></span>some text</div>
   <div><span class="a3"></span>some text</div>
</div>

隣接するクラスの場合にのみ<a>、すべてを取得することに興味があります。したがって、コード全体の最後で、私の結果は1番目と3番目の結果になるはずです。中にあるか、属性があるとしたら簡単ですが、運がありません。some text spana1<a>divsome text<a>some textspandivclass

私が今していることはspana1クラスで探すことです:

//div[contains(@class,'foo')]/div/span[contains(@class,'a1')]

次に、その親を取得し、その親query()をコンテキストノードとして別の操作を行います。これは単に効率的とはほど遠いように見えるので、問題は明らかに私の目標を達成するためのより良い方法があるかどうかです。


回答の補遺

@MarcBが受け入れた回答によると、使用する正しいクエリは次のとおりです。

//div[contains(@class,'foo')]/div/span[contains(@class,'a1')]/..

しかし、<a>それを使用する方が良いかもしれません:

//div[contains(@class,'foo')]/div/span[contains(@class,'a1')]/../a

<a>コンテナの代わりに取得します。

4

2 に答える 2

55

xpath クエリの良いところは、基本的にファイル システム パスのように扱えることです。

//div[contains(@class,'foo')]/div/span[contains(@class,'a1')]/..
                                                              ^^

は、.foo ノードの下にあるすべての .a1 ノードを検出し、1 レベル上に移動して a1 ノードの親に移動します。

于 2012-10-13T17:35:15.160 に答える
16

逆軸を使用するよりも優れた式:

//div[contains(@class,'foo')]/div[span[contains(@class,'a1')]]

これdivにより、div属性classに文字列 "foo" が含まれる の子であり、属性に文字列 "a1" が含まれる子をdiv持つ (選択された ) が選択されます。spanclass

XSLT ベースの検証:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:copy-of select=
  "//div[contains(@class,'foo')]
          /div[span[contains(@class,'a1')]]"/>
 </xsl:template>
</xsl:stylesheet>

この変換が提供された XML ドキュメントに適用されると、次のようになります。

<div class="foo">
   <div><span class="a1"></span><a href="...">...</a></div>
   <div><span class="a2"></span><a href="...">...</a></div>
   <div><span class="a1"></span>some text</div>
   <div><span class="a3"></span>some text</div>
</div>

XPath 式が評価され、選択された要素が出力にコピーされます。

<div>
   <span class="a1"/>
   <a href="...">...</a>
</div>
<div>
   <span class="a1"/>some text</div>

Ⅱ.クラスの 1 つによる Html 要素へのアクセスに関する注意事項:

要素が 1 つのクラスしか持てないことがわかっている場合は、使用する必要はまったくありません。contains()

使用しないでください:

//div[contains(@class, 'foo')]

使用:

//div[@class = 'foo']

または、先頭/末尾のスペースがある可能性がある場合は、次を使用します。

//div[normalize-space(@class) = 'foo']

の重大な問題:

//div[contains(@class, 'foo')]

divこれは、「myfoo」、「foo2」、「myfoo3」などのクラスを持つものを選択するということです。

要素が複数のクラスを持つ可能性があり、上記の問題を回避するための正しい XPath 式は次のとおりです。

//div[contains(concat(' ', @class, ' '), ' foo ')]
于 2012-10-13T17:50:57.067 に答える