6

大きな HTML ページがあります。しかし、Xpath を使用して特定のノードを選択したい:

<html>
 ........
<!-- begin content -->
 <div>some text</div>
 <div><p>Some more elements</p></div>
<!-- end content -->
.......
</html>

使用後にHTMLを選択できます<!-- begin content -->

"//comment()[. = ' begin content ']/following::*" 

<!-- end content -->また、使用する前に HTML を選択できます。

"//comment()[. = ' end content ']/preceding::*" 

しかし、2 つのコメントの間のすべての HTML を選択するには、XPath が必要ですか?

4

1 に答える 1

19

最初のコメントが前にあり、2 番目のコメントが後に続く要素を探します。

doc.xpath("//*[preceding::comment()[. = ' begin content ']]
              [following::comment()[. = ' end content ']]")
#=> <div>some text</div>
#=> <div>
#=>   <p>Some more elements</p>
#=> </div>
#=> <p>Some more elements</p>

上記は、その間の要素を提供することに注意してください。これは、返された各ノードを反復処理すると、ネストされた重複したノードがいくつか取得されることを意味します。

実際には、トップレベルのノード、つまりコメントの兄弟を間に入れたいと思うかもしれません。これは、代わりに を使用して実行できますpreceding/following-sibling

doc.xpath("//*[preceding-sibling::comment()[. = ' begin content ']]
              [following-sibling::comment()[. = ' end content ']]")
#=> <div>some text</div>
#=> <div>
#=>   <p>Some more elements</p>
#=> </div>

更新 - コメントを含む

//*コメント (およびその他のいくつか) を含まない要素ノードのみを返します。*に変更してnode()、すべてを返すことができます。

puts doc.xpath("//node()[preceding-sibling::comment()[. = 'begin content']]
                        [following-sibling::comment()[. = 'end content']]")
#=> 
#=> <!--keywords1: first_keyword-->
#=> 
#=> <div>html</div>
#=> 

要素ノードとコメントだけが必要な場合 (つまり、すべてではない場合)、self軸を使用できます。

doc.xpath("//node()[self::* or self::comment()]
                   [preceding-sibling::comment()[. = 'begin content']]
                   [following-sibling::comment()[. = 'end content']]")
#~ #=> <!--keywords1: first_keyword-->
#~ #=> <div>html</div>
于 2013-09-18T13:09:49.477 に答える