获取节点中的特定标记



我正在使用Ruby, XPath和Nokogiri,并试图从以下XML检索d1:

<a>
  <b1>
    <c>
      <d1>01/11/2001</d1>
      <d2>02/02/2004</d2>
    </c>
  </b1>
</a>

这是我的循环代码:

rs = doc.xpath("//a/b1/c/d1").inner_text
puts rs

它不返回任何东西(没有错误)。

我想在<d1>中获取文本

不要在xpath查询中询问文本内容:

rs = doc.xpath('//a/b1/c/d1/text()')

您在错误地使用XPath:

require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<a>
  <b1>
    <c>
      <d1>01/11/2001</d1>
      <d2>02/02/2004</d2>
    </c>
  </b1>
</a>
EOT
doc.at('/a/b1/c/d1').text # => "01/11/2001"
doc.at('//d1').text # => "01/11/2001"

//在XPath-ese中意味着从顶部开始并查看文档中的任何位置。相反,如果您提供显式/绝对选择器,请从文档的顶部开始,并使用'/a/b1/c/d1'向下钻取。或者,执行简单的操作,让解析器使用//d1在文档中搜索特定节点。如果知道该节点只有一个实例,就可以这样做。

在上面的代码中,我使用at而不是xpathat返回第一个匹配节点,这与使用xpath('//d1').first类似。xpath返回一个NodeSet,类似于一个节点数组,而at只返回一个Node。在NodeSet上使用inner_text可能不会给您想要的结果,这些结果可能是特定节点的文本,因此要小心。

doc.xpath('/a/b1/c/d1/text()').class # => Nokogiri::XML::NodeSet
doc.xpath('//c').inner_text # => "n      01/11/2001n      02/02/2004n    "
doc.xpath('/a/b1/c/d1').first.text # => "01/11/2001"

看下面几行。我没有使用XPath选择器,而是使用了更具可读性的CSS。Nokogiri都支持。

doc.at('d1').text # => "01/11/2001"
doc.at('a b1 c d1').text # => "01/11/2001"

另外,请注意从这两行返回的数据类型:

doc.at('/a/b1/c/d1/text()').class # => Nokogiri::XML::Text
doc.at('/a/b1/c/d1').text.class # => String

虽然告诉解析器在<d1>中找到text()节点似乎很好/聪明,但返回的不是文本,需要进一步访问才能使其可用,所以考虑放弃使用text(),除非您确切地知道为什么需要它:

doc.at('/a/b1/c/d1/text()').text # => "01/11/2001"

最后,Nokogiri有许多用于定位节点的方法。如上所述,xpath返回一个NodeSet, at返回一个Node。xpath实际上是Nokogiri的search方法的xpath特定版本。search, cssxpath都返回nodeset。atat_cssat_xpath均返回节点。当您有一个模棱两可的选择器,需要将其用作CSS或XPath时,CSS和XPath变体非常有用。大多数情况下,Nokogiri可以自己判断它是CSS还是XPath,并且会做正确的事情,因此在大多数代码中使用通用的searchat是可以的。当你必须指定一个或另一个时,使用特定的版本

相关内容

  • 没有找到相关文章

最新更新