我有以下HTML结构,我想找到<div>xyz</div>
之后的所有兄弟节点和节点,直到HTML的最后一个节点:
<html>
<head>
</head>
<body>
<div id="page-container">
<div id="page-1">
<p> abc <p>
<div>xyz</div>
<p>bbb</p>
<b>hhhh</b>
</div>
<div id="page-2">
<p>hhhh</p>
<span>abc</span>
<p> gggg </p>
</div>
<div id="page-3">
<p>hhhh</p>
<span>abc</span>
<p> gggg </p>
</div>
</div>
</body>
</html>
我用过
xpath('//div[contains(text(), "xyz")]/following-sibling::*')
但它没有返回所有节点,它只提供<p>bbb</p><b>hhhh</b>
个节点。
我期待以下输出:
<div id="page-container">
<div id="page-1">
<div>xyz</div>
<p>bbb</p>
<b>hhhh</b>
</div>
<div id="page-2">
<p>hhhh</p>
<span>abc</span>
<p> gggg </p>
</div>
<div id="page-3">
<p>hhhh</p>
<span>abc</span>
<p> gggg </p>
</div>
</div>
如何获取特定节点之后出现的所有节点?
答案 0 :(得分:0)
从HTML或XML中提取信息最困难的事情之一是确定从哪里开始捕获。如果你想要捕获大量类似的节点,然后删除你不想要的东西,那么通常更容易从所需的节点开始,然后删除它,而不是零碎地工作并尝试重建某些结构。
我会这样做:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<html>
<head>
</head>
<body>
<div id="page-container">
<div id="page-1">
<p> abc <p>
<div>xyz</div>
<p>bbb</p>
<b>hhhh</b>
</div>
<div id="page-2">
<p>hhhh</p>
<span>abc</span>
<p> gggg </p>
</div>
<div id="page-3">
<p>hhhh</p>
<span>abc</span>
<p> gggg </p>
</div>
</div>
</body>
</html>
EOT
page_container = doc.at('#page-container')
page1 = page_container.at('#page-1')
page1.children = page1.children[3..-1]
结果是:
puts page_container.to_html
# >> <div id="page-container">
# >> <div id="page-1">
# >> <div>xyz</div>
# >> <p>bbb</p>
# >> <b>hhhh</b>
# >> </div>
# >> <div id="page-2">
# >> <p>hhhh</p>
# >> <span>abc</span>
# >> <p> gggg </p>
# >> </div>
# >> <div id="page-3">
# >> <p>hhhh</p>
# >> <span>abc</span>
# >> <p> gggg </p>
# >> </div>
# >> </div>
注意:
我在“page-1”div中使用偏移量跳过前三个节点:有一个文本节点,<p>
节点后跟另一个文本节点:
page_container.at('#page-1').children[0,3]
# => [#<Nokogiri::XML::Text:0x3fdb6d196b48 "\n ">, #<Nokogiri::XML::Element:0x3fdb6d1979a8 name="p" children=[#<Nokogiri::XML::Text:0x3fdb6d1b7d48 " abc ">]>, #<Nokogiri::XML::Element:0x3fdb6d1b7af0 name="p" children=[#<Nokogiri::XML::Text:0x3fdb6d1b7870 "\n ">]>]
我通常使用remove
来摆脱<p> abc <p>
,但我看到的是Nokogiri 1.6.6.2中的错误导致:
page_container.at('#page-1 p').remove
puts page_container.to_html
# >> <div id="page-container">
# >> <div id="page-1">
# >> <p>
# >> </p>
# >> <div>xyz</div>
已为此创建错误报告。