ruby - 将 XPath 与 HTML 或 XML 片段一起使用?

标签 ruby xpath nokogiri

我是 Nokogiri 和 XPath 的新手,我正在尝试访问 HTML 或 XML 片段中的所有注释。 当我不使用 fragment 函数时,XPaths .//comment()//comment() 可以工作,但它们找不到任何带有片段的东西。使用标记而不是注释,它适用于第一个 XPath。

通过反复试验,我意识到在这种情况下 comment() 只能找到顶级评论,而 .//comment() 和其他一些只能找到内部评论.难道我做错了什么?我错过了什么?谁能解释发生了什么?

我应该使用什么 XPath 来获取 Nokogiri 解析的 HTML 片段中的所有评论?

这个例子可以帮助理解问题:

str = "<!-- one --><p><!-- two --></p>"

# this works:
Nokogiri::HTML(str).xpath("//comment()")
=> [#<Nokogiri::XML::Comment:0x3f8535d71d5c " one ">, #<Nokogiri::XML::Comment:0x3f8535d71cf8 " two ">]
Nokogiri::HTML(str).xpath(".//comment()")
=> [#<Nokogiri::XML::Comment:0x3f8535cc7974 " one ">, #<Nokogiri::XML::Comment:0x3f8535cc7884 " two ">]

# with fragment, it does not work:
Nokogiri::HTML.fragment(str).xpath("//comment()")
=> []
Nokogiri::HTML.fragment(str).xpath("comment()")
=> [#<Nokogiri::XML::Comment:0x3f8535d681a8 " one ">]
Nokogiri::HTML.fragment(str).xpath(".//comment()")
=> [#<Nokogiri::XML::Comment:0x3f8535d624d8 " two ">]
Nokogiri::HTML.fragment(str).xpath("*//comment()")
=> [#<Nokogiri::XML::Comment:0x3f8535d5cb8c " two ">]
Nokogiri::HTML.fragment(str).xpath("*/comment()")
=> [#<Nokogiri::XML::Comment:0x3f8535d4e104 " two ">]

# however it does if it is a tag instead of a comment:
str = "<a desc='one'/> <p><a>two</a><a desc='three'/></p>"
Nokogiri::HTML.fragment(str).xpath(".//a")
=> [#<Nokogiri::XML::Element:0x3f8535cb44c8 name="a" attributes=[#<Nokogiri::XML::Attr:0x3f8535cb4194 name="desc" value="one">]>, #<Nokogiri::XML::Element:0x3f8535cb4220 name="a" children=[#<Nokogiri::XML::Text:0x3f8535cb3ba4 "two">]>, #<Nokogiri::XML::Element:0x3f8535cb3a3c name="a" attributes=[#<Nokogiri::XML::Attr:0x3f8535cb3960 name="desc" value="three">]>]

PS:没有 fragment 它会做我想做的事,但它也添加了一些东西,比如“DOCTYPE”,我实际上只有一个我正在编辑的 HTML 文件的片段(删除一些标签,替换其他人)。

最佳答案

//comment()/descendant-or-self::node()/child::comment()

的缩写形式

将此 xpath 与片段一起使用会忽略根注释(它们由 /descendant-or-self::node() 选择,但它们没有子节点)。

如果您使用HTML(str),您将创建一个文档节点作为所有其他项目的根。因此,/descendant-or-self::node()/child::comment() 不会忽略顶级注释,因为它们是文档节点的子节点(它本身由 /descendant-or-self::node()).

我不确定为什么 descendant::comment() 在任何情况下都有效,我会说它应该是 descendant-or-self::comment() , 但没关系。

希望对您有所帮助?

关于ruby - 将 XPath 与 HTML 或 XML 片段一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3817843/

相关文章:

ruby - Array.empty 的相反方法是什么?或 [].empty?在 ruby

ruby-on-rails - 在将用户输入传递给 %x(执行它)之前,我应该如何清理用户输入?

ruby - 如何使用 ruby​​/nokogiri 解析 html 源代码?

ruby-on-rails - 使用 Nokogiri 查找 id 包括 [] 的标签

ruby-on-rails - 无效的 gem : package is corrupt -- while installing rails in osx yosemite 10. 10.1

ruby - 在 Nokogiri 中,如何找到文档中某个节点之前的所有节点?

javascript - 哪种脚本语言更适合嵌入多线程 C/C++ 应用程序

ruby - 导轨 4 : Append to a "has_many" relation without saving to DB

perl - 获取 XML::XPath 中的节点集大小

selenium - Selenium IDE 中的 XPATH : Matching text in a <td> tag that contains <br> tags