2

次の構造からデータを抽出しようとしています。

<span>Heading</span>
<br />
<br />
<span>Heading1</span>
<br />
data#1
<br />
<br />
<span>Heading4</span><br />
&acirc;&euro;&cent; data#4.1
<br />
&acirc;&euro;&cent; data#4.2
<br />
&acirc;&euro;&cent; data#4.3
<br />
&acirc;&euro;&cent; data#4.4
<br />
<br />
<span>Heading5</span>
<br />
&acirc;&euro;&cent; data#5.1
<br />
&acirc;&euro;&cent; data#5.2
<br />
&acirc;&euro;&cent; data#5.3
<br />
<br />

次のようなものを使用して data#1 を抽出できます。

span[text()='Heading1']/following-sibling::br[1]/following::text()[1]

しかし、Heading4 の下のデータを抽出する方法がわかりません。data#4.1, data#4.2, data#4.3&を抽出する必要がありdata#4.4ます。ポイント数は固定ではなく、変動する可能性があります。

4

4 に答える 4

3

この XPath 1.0 式は、必要なノードを正確に選択します

  /*/span[.='Heading4']
        /following-sibling::text()
           [count(.|/*/span[.='Heading5']/preceding-sibling::text())
           =
            count(/*/span[.='Heading5']/preceding-sibling::text())
            ]
                  [normalize-space()]

$ns1これは、2 つのノードセットとの共通部分に対するよく知られた Kayessian 法から生成されます$ns2

$ns1[count(.|$ns2) = count($ns2)]

上記の最初の式は、Kayess 式に次の式を代入$ns1すると得られます。

  /*/span[.='Heading4']/following-sibling::text()

そして$ns2

  /*/span[.='Heading5']/preceding-sibling::text()

最後の述語[normalize-space()]は、この共通部分から空白のみのテキスト ノードを除外します。

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=
      "/*/span[.='Heading4']
            /following-sibling::text()
               [count(.|/*/span[.='Heading5']/preceding-sibling::text())
               =
                count(/*/span[.='Heading5']/preceding-sibling::text())
                ]
                [normalize-space()]
      "/>
 </xsl:template>
</xsl:stylesheet>

提供された XML ドキュメントにこの変換が適用されると(エンティティが置き換えられます -- 利用可能なエンティティを定義する DTD がなく、ここでは必須ではないため):

<html>
    <span>Heading</span>
    <br />
    <br />
    <span>Heading1</span>
    <br /> data#1 
    <br />
    <br />
    <span>Heading4</span>
    <br /> #acirc;#euro;#cent; data#4.1 
    <br /> #acirc;#euro;#cent; data#4.2 
    <br /> #acirc;#euro;#cent; data#4.3 
    <br /> #acirc;#euro;#cent; data#4.4 
    <br />
    <br />
    <span>Heading5</span>
    <br /> #acirc;#euro;#cent; data#5.1 
    <br /> #acirc;#euro;#cent; data#5.2 
    <br /> #acirc;#euro;#cent; data#5.3 
    <br />
    <br />
</html>

Xpath 式が評価され、この評価の結果が出力にコピーされます。

 #acirc;#euro;#cent; data#4.1 
     #acirc;#euro;#cent; data#4.2 
     #acirc;#euro;#cent; data#4.3 
     #acirc;#euro;#cent; data#4.4 
于 2012-07-30T12:39:27.137 に答える
2

使用できます

span[text()='Heading4']/following-sibling::text()[. != ""] 

Heading4 の後のすべてのテキストを取得してから使用します。

span[text()='Heading5']/following-sibling::text()[. != ""]

Heading5 の後に不要なテキストを取得し、メイン プログラムで最初の結果セットから 2 番目の結果セットを減算します。

また、XPath 2 がある場合は、except演算子を使用して直接除外できます。

span[text()='Heading4']/following-sibling::text()[. != ""] except span[text()='Heading5']/following::text()[. != ""]

関数を使用して beforedataなしでのみ取得できるため、最終的な XPath 2 式は次のようになります。&acirc;&euro;&cent;substring(.,5)

(span[text()='Heading4']/following-sibling::text()[. != ""] except span[text()='Heading5']/following::text()[. != ""])/substring(., 5)

また、言語要件を明示的に述べていないため、パスカルベースのクエリ言語も確認することをお勧めします。これは、はるかに優れているためです。

 <span>Heading4</span><br />
 <t:loop>
    {filter(text(), "data.*")}<br/>
 </t:loop>
 <br/>
 <span>Heading5</span><br />
于 2012-07-30T11:23:47.837 に答える
1

ここでの答えの助けを借りて、私は最終的にこれを使用することになりました

//text()[preceding-sibling::span[1] = 'Heading4']

于 2012-07-30T12:02:25.690 に答える
0

私は使うだろう

span[text()='Heading4']/following-sibling::text()

結果のテキストを個別に解析します。

于 2012-07-30T11:01:43.150 に答える