2

私は Nokogiri と Ruby を使用していくつかの HTML を解析しようとしています。サンプル ファイルは次のようになります。

<div id="main-body">
  <p>
    <span>First Text</span>
    <span>Second Text</span>
    <span>Third Text</span>
    <span>Fourth Text</span>
    <br>
    <span>Fifth Text</span>
    <span>Sixth Text</span>
    <span>Seventh Text</span>
    <br>
    <span>Eight Text</span>
    <span>Ninth Text</span>
    <br>
  </p>
</div

ランダムな区切りタグの間または最初の区切りの前のテキストのみを通過して選択する方法を見つけようとしています。

基本的には、通過するたびに出力を変えたいと思っています。したがって、出力例は次のようになります

=>First Text
=>Second Text
=>Third Text
=>Fourth Text

あるときは、おそらく次回はブレーク 2 と 3 の間にあるものを取得します。

=>Eight Text
=>Ninth Text

HTML の改行の数を数えることができれば、rand() を使用してランダムな改行を選択し、次の改行に到達するまでテキストを出力できると考えていますが、正しく取得できません。

これまでの私のコードは、ページ全体を Nokogiri 型にロードし、そこから解析しようとしていました。

doc = Nokogiri::HTML(open(targeturl))
puts doc.xpath("./br").length #gives me the count of break tags in the document

そこから実際にブレークを変数に割り当てて、それらに 1 つずつアクセスできますが、どこに行けばいいのか、ここから正しい軌道に乗っているのかさえわからず、混乱しているように感じます点 :/

4

4 に答える 4

1

さらに別のオプションはslice_beforeです。

doc.search('p *').slice_before{|x| x.name == 'br'}.each do |slice|
  puts '*', slice.select{|x| x.name == 'span'}
end
于 2012-09-28T00:58:40.033 に答える
1

count()およびを使用して、前の br タグの数に基づいてノードを取得できますpreceding-sibling

puts doc.xpath("//span[count(preceding-sibling::br)=0]")
#=> <span>First Text</span>
#=> <span>Second Text</span>
#=> <span>Third Text</span>
#=> <span>Fourth Text</span>

puts doc.xpath("//span[count(preceding-sibling::br)=1]")
#=> <span>Fifth Text</span>
#=> <span>Sixth Text</span>
#=> <span>Seventh Text</span>

puts doc.xpath("//span[count(preceding-sibling::br)=2]")
#=> <span>Eight Text</span>
#=> <span>Ninth Text</span>

ランダムに選択するには、前の兄弟の数をランダム化します。

puts doc.xpath("//span[count(preceding-sibling::br)=#{rand(doc.xpath("//br").length)}]")
于 2012-09-27T15:54:17.170 に答える
0

$k以下は、 -thの前で-1thbrの前ではなく、すべてのテキスト ノードを選択する単一の XPath ワンライナー式です。$kbr

/*/p/br[2]/preceding-sibling::*[count(preceding-sibling::br)=1]/text()

したがって、kinterval[1, count(/*/p/br)]に乱数がある場合は、単純に上記の Xpath 式に置き換えて評価します。

XSLT ベースの検証:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output  method="text"/>

 <xsl:template match="/">
     <xsl:copy-of select=
     "/*/p/br[2]/preceding-sibling::*[count(preceding-sibling::br)=1]/text()
     "/>
 </xsl:template>
</xsl:stylesheet>

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

<div id="main-body">
    <p>
        <span>First Text</span>
        <span>Second Text</span>
        <span>Third Text</span>
        <span>Fourth Text</span>
        <br/>
        <span>Fifth Text</span>
        <span>Sixth Text</span>
        <span>Seventh Text</span>
        <br/>
        <span>Eight Text</span>
        <span>Ninth Text</span>
        <br/>
    </p>
</div>

XPath 式が評価され、この評価の結果 (選択されたすべてのテキスト ノード) が出力にコピーされます

Fifth TextSixth TextSeventh Text
于 2012-09-27T17:30:34.227 に答える