4

どのようにすればよいか、アドバイスをお待ちしています。xpathのみで解決策を試しています:

HTML の例:

<div>
  <div>
    <div>text div (leaf)</div>
    <p>text paragraph (leaf)</p>
  </div>
</div>
<p>text paragraph 2 (leaf)</p>

コード:

doc = Nokogiri::HTML.fragment("- the html above -")
result = doc.xpath("*[not(child::*)]")


[#<Nokogiri::XML::Element:0x3febf50f9328 name="p" children=[#<Nokogiri::XML::Text:0x3febf519b718 "text paragraph 2 (leaf)">]>] 

しかし、この xpath は最後の "p" しか提供しません。私が望むのは、葉ノードのみを返すフラット化動作のようなものです。

以下は、stackoverflow の参照回答です。

XPath式を使用してすべてのリーフノードを選択するには?

XPath - 特定の型の子を持たないノードを取得する

ありがとう

4

3 に答える 3

7

次を使用して、子要素を持たないすべての要素ノードを見つけることができます。

//*[not(*)]

例:

require 'nokogiri'

doc = Nokogiri::HTML.parse <<-end
<div>
  <div>
    <div>text div (leaf)</div>
    <p>text paragraph (leaf)</p>
  </div>
</div>
<p>text paragraph 2 (leaf)</p>
end

puts doc.xpath('//*[not(*)]').length
#=> 3

doc.xpath('//*[not(*)]').each do |e|
    puts e.text
end
#=> "text div (leaf)"
#=> "text paragraph (leaf)"
#=> "text paragraph 2 (leaf)"
于 2013-07-26T20:14:37.963 に答える
2

XPath では、テキスト自体がノードであるため、コメントを指定すると、コンテンツを含むタグではなく、タグのコンテンツのみを選択する必要がありますが、<br/>(存在する場合) をキャプチャします。

他の要素(タグ)を含まないすべての要素を探していると思います(これはまさにあなたが求めていたものではありません)-その後、@ Justin Koの答えで問題なく、XPath式を使用します

//*[not(*)]

本当にすべてのリーフノードを探したい場合は、*セレクターを使用できませんが、使用する必要がありますnode():

//node()[not(node())]

ノードは要素にすることができますが、テキスト ノード、コメント、処理命令、属性、さらには XML ドキュメント (ただし、他の要素内に存在することはできません) にすることもできます。

本当にテキストノード//text()のみが必要な場合は、 @Priti が提案したように進みます。これは、実際に、要求しているノードを正確に選択します(リーフノードが定義されているものではなく、それらを強調表示することによって)。

于 2013-07-26T21:38:37.710 に答える