3

次の div 要素が与えられた場合

<div class="info">
    <a href="/s/xyz.html" class="title">title</a>
    <span class="a">123</span>
    <span class="b">456</span>
    <span class="c">789</span>
</div>

クラス「b」でスパンの内容を取得したい。ただし、解析したい一部の div には、2 番目の 2 つのスパン (クラス「b」と「c」) がありません。これらの div については、クラス "a" のスパンの内容が必要です。これを選択する単一の XPath 式を作成することは可能ですか?

不可能な場合、div の内容全体を取得するセレクターを作成することは可能ですか? つまり、取得します

<a href="/s/xyz.html" class="title">title</a>
<span class="a">123</span>
<span class="b">456</span>
<span class="c">789</span>

それができれば、正規表現を使用して必要なデータを見つけることができます。(div内のテキストを選択できますが、タグも選択する方法がわかりません。テキストだけで123456789が得られます。)

4

3 に答える 3

2

より効率的 -- ユニオンは必要ありません:

   //div/span
          [@class='b'
           or
             @class='a'
            and
             not(parent::*[span[@class='b']])
           ]

2 つの絶対的な「//式」の結合である式 (以下のような) は、通常、2 つの完全なドキュメント ツリー トラバーサルを実行し、次に結合操作で重複排除とドキュメント順の並べ替えを実行します。 XPath プロセッサにインテリジェントなオプティマイザがない限り、ツリー トラバーサル。

そのような非効率的な表現の例:

//div/span[@class='b'] | //div[not(./span[@class='b'])]/span[@class='a'] 

XSLT ベースの検証:

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

 <xsl:template match="/">
  <xsl:copy-of select=
  "//div/span
          [@class='b'
           or
             @class='a'
            and
             not(parent::*[span[@class='b']])
           ]"/>
 </xsl:template>
</xsl:stylesheet>

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

<div class="info">
    <a href="/s/xyz.html" class="title">title</a>
    <span class="a">123</span>
    <span class="b">456</span>
    <span class="c">789</span>
</div>

Xpath 式が評価され、選択された要素 (この場合は 1 つだけ) が出力にコピーされます

<span class="b">456</span>

が存在しない別の XML ドキュメントに同じ変換を適用すると、次のようになりclass='b'ます。

<div class="info">
    <a href="/s/xyz.html" class="title">title</a>
    <span class="a">123</span>
    <span class="x">456</span>
    <span class="c">789</span>
</div>

同じ XPath 式が評価され、正しく選択された要素が出力にコピーされます

<span class="a">123</span>
于 2012-07-12T15:42:33.820 に答える
1

xpath 式は次のようになります。

//div/span[@class='b'] | //div[not(./span[@class='b'])]/span[@class='a']

ユニオン演算子の左側の式は、|すべての div 内のすべての b クラス スパンを選択します。右側の式は、最初に b クラス スパンを持たないすべての div をクエリし、次にそれらの a クラス スパンを選択します。| | 演算子は、2 つのセットの結果を結合します。

not() を使用してノードを選択する方法についてはこちらを参照してください。オペレーター。

また、質問の 2 番目の部分を参照するには、こちらをご覧ください。xpath で node() を使用すると、選択したノードの下にあるすべて (ノード + テキスト) を選択できます。したがって、返された div 内のすべてを取得できます

//div/node()

他の手段による将来の処理のために。

于 2012-07-11T19:47:44.000 に答える
0

ユニオン演算子なしで入力に作用する式:

//div/span[@class='a' or @class='b'][count(../span[@class='b']) + 1]

これはただの楽しみです。私はおそらく、プロダクションコードで@inVaderの答えのようなものを使用するでしょう。

于 2012-07-11T21:15:17.540 に答える