Ruby 为什么xpath.each返回一个元素而不是一个节点?

Ruby 为什么xpath.each返回一个元素而不是一个节点?,ruby,nokogiri,Ruby,Nokogiri,我想迭代xpath搜索的结果,这样我就可以处理节点了。Nokogiri的文档和示例说,xpath返回一个节点集和NodeSet。每个返回一个节点,这是我想要的,但是我得到了一个元素。我做错了什么 这段简化的代码突出了这个问题。关于StackOverflow有许多相关的问题,尽管它们是特定于域的,模糊了这个问题,并且与这个问题不完全匹配 <?xml version="1.0" encoding="UTF-8" standalone="no"?> <root xmlns="http

我想迭代
xpath
搜索的结果,这样我就可以处理节点了。Nokogiri的文档和示例说,
xpath
返回一个节点集和
NodeSet。每个
返回一个节点,这是我想要的,但是我得到了一个元素。我做错了什么

这段简化的代码突出了这个问题。关于StackOverflow有许多相关的问题,尽管它们是特定于域的,模糊了这个问题,并且与这个问题不完全匹配

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root xmlns="http://example.org/1">

  <item>
    <value>One</value>
  </item>

  <item>
    <value>Two</value>
  </item>
</root>

根据每个请求的注释转换为:

元素
节点。(并非每个
节点
都是
元素

元素是一种节点吗? Nokogiri::XML::Element正确 #我从xpath获得的每个节点都是节点吗? xpath(“//xmlns:value”)。全部?{| node | node.is|a?(Nokogiri::XML::node)} #=>正确 #我可以从xpath中获取的每个节点中获取父节点吗? xmldoc.xpath(“//xmlns:value”).map{| node | node.parent.name} #=>[“项目”,“项目”]
根据每个请求的注释进行转换:

元素
节点。(并非每个
节点
都是
元素

元素是一种节点吗? Nokogiri::XML::Element正确 #我从xpath获得的每个节点都是节点吗? xpath(“//xmlns:value”)。全部?{| node | node.is|a?(Nokogiri::XML::node)} #=>正确 #我可以从xpath中获取的每个节点中获取父节点吗? xmldoc.xpath(“//xmlns:value”).map{| node | node.parent.name} #=>[“项目”,“项目”]
这可能有助于澄清发生了什么:

require 'nokogiri'

types = {
  1 => 'ELEMENT_NODE',
  2 => 'ATTRIBUTE_NODE',
  3 => 'TEXT_NODE',
  4 => 'CDATA_SECTION_NODE',
  5 => 'ENTITY_REF_NODE',
  6 => 'ENTITY_NODE',
  7 => 'PI_NODE',
  8 => 'COMMENT_NODE',
  9 => 'DOCUMENT_NODE',
  10 => 'DOCUMENT_TYPE_NODE',
  11 => 'DOCUMENT_FRAG_NODE',
  12 => 'NOTATION_NODE',
  13 => 'HTML_DOCUMENT_NODE',
  14 => 'DTD_NODE',
  15 => 'ELEMENT_DECL',
  16 => 'ATTRIBUTE_DECL',
  17 => 'ENTITY_DECL',
  18 => 'NAMESPACE_DECL',
  19 => 'XINCLUDE_START',
  20 => 'XINCLUDE_END',
  21 => 'DOCB_DOCUMENT_NODE',
}

doc = Nokogiri::XML.parse(<<EOT)
<xml>
  <t1>foo</t1>
  bar
</xml>
EOT

doc.xpath('//.').each do |n|
  puts "'%s' is a %s containing \"%s\"" % [n.name, types[n.type], n.content]
end
Nokogiri下有一个类似解析器的解析器,它将XML或HTML分解为各种不同类型的节点,然后将这些节点传递回Nokogiri

根据搜索访问器的不同,您可以获得各种类型中的任何一种,但通常最有用的是文档中的标记:

doc.xpath('//t1').each do |n|
  puts "'%s' is a %s containing \"%s\"" % [n.name, types[n.type], n.content]
end
# >> 't1' is a ELEMENT_NODE containing "foo"
通过这些,我们可以搜索或导航感兴趣的文档查找节点,查找和提取其内容,或隔离部分,移动、更改或删除它们,或插入新内容

有时我们关心文本节点,因为我们希望插入文本或破坏格式:

doc.xpath('//text()').each do |n|
  puts "'%s' is a %s containing %s" % [n.name, types[n.type], n.content.inspect]
end
# >> 'text' is a TEXT_NODE containing "\n  "
# >> 'text' is a TEXT_NODE containing "foo"
# >> 'text' is a TEXT_NODE containing "\n  bar\n"

这可能有助于“展示你看到的东西,激发你对引擎盖下其他东西的好奇心。”

这可能有助于澄清发生了什么:

require 'nokogiri'

types = {
  1 => 'ELEMENT_NODE',
  2 => 'ATTRIBUTE_NODE',
  3 => 'TEXT_NODE',
  4 => 'CDATA_SECTION_NODE',
  5 => 'ENTITY_REF_NODE',
  6 => 'ENTITY_NODE',
  7 => 'PI_NODE',
  8 => 'COMMENT_NODE',
  9 => 'DOCUMENT_NODE',
  10 => 'DOCUMENT_TYPE_NODE',
  11 => 'DOCUMENT_FRAG_NODE',
  12 => 'NOTATION_NODE',
  13 => 'HTML_DOCUMENT_NODE',
  14 => 'DTD_NODE',
  15 => 'ELEMENT_DECL',
  16 => 'ATTRIBUTE_DECL',
  17 => 'ENTITY_DECL',
  18 => 'NAMESPACE_DECL',
  19 => 'XINCLUDE_START',
  20 => 'XINCLUDE_END',
  21 => 'DOCB_DOCUMENT_NODE',
}

doc = Nokogiri::XML.parse(<<EOT)
<xml>
  <t1>foo</t1>
  bar
</xml>
EOT

doc.xpath('//.').each do |n|
  puts "'%s' is a %s containing \"%s\"" % [n.name, types[n.type], n.content]
end
Nokogiri下有一个类似解析器的解析器,它将XML或HTML分解为各种不同类型的节点,然后将这些节点传递回Nokogiri

根据搜索访问器的不同,您可以获得各种类型中的任何一种,但通常最有用的是文档中的标记:

doc.xpath('//t1').each do |n|
  puts "'%s' is a %s containing \"%s\"" % [n.name, types[n.type], n.content]
end
# >> 't1' is a ELEMENT_NODE containing "foo"
通过这些,我们可以搜索或导航感兴趣的文档查找节点,查找和提取其内容,或隔离部分,移动、更改或删除它们,或插入新内容

有时我们关心文本节点,因为我们希望插入文本或破坏格式:

doc.xpath('//text()').each do |n|
  puts "'%s' is a %s containing %s" % [n.name, types[n.type], n.content.inspect]
end
# >> 'text' is a TEXT_NODE containing "\n  "
# >> 'text' is a TEXT_NODE containing "foo"
# >> 'text' is a TEXT_NODE containing "\n  bar\n"

这可能有助于“展示你所看到的东西,激发你对引擎盖下还有什么东西的好奇心。

一个
元素
是一个
节点
。(并非每个
节点
都是
元素
)想象一下“我去宠物店买了一些动物,但他们卖给我的是小猫,而不是动物!”谢谢。我不能在我的元素上做像.parent这样的小事情,但您的澄清确认了这一定是我代码中的其他错误。是否要将您的注释转换为答案?
元素
是一个
节点
。(并非每个
节点
都是
元素
)想象一下“我去宠物店买了一些动物,但他们卖给我的是小猫,而不是动物!”谢谢。我不能在我的元素上做像.parent这样的小事情,但您的澄清确认了这一定是我代码中的其他错误。您想将您的评论转换为答案吗?非常有用,谢谢。你的贡献应该在稀疏的Nokogiri中找到一席之地。这些文档相当不错,但它们非常面向有经验的Ruby程序员。教程和备忘单也是如此,因此初学者很难仅仅学习如何处理解析器和搜索XML/HTML。我从更原始的开始,然后很早就迁移到Ruby,所以对我来说这不是一个很大的进步,只是更健壮。非常有用,谢谢。你的贡献应该在稀疏的Nokogiri中找到一席之地。这些文档相当不错,但它们非常面向有经验的Ruby程序员。教程和备忘单也是如此,因此初学者很难仅仅学习如何处理解析器和搜索XML/HTML。我从更原始的开始,然后很早就迁移到Ruby,所以对我来说这并不是一个很大的进步,只是更加健壮。
doc.xpath('//text()').each do |n|
  puts "'%s' is a %s containing %s" % [n.name, types[n.type], n.content.inspect]
end
# >> 'text' is a TEXT_NODE containing "\n  "
# >> 'text' is a TEXT_NODE containing "foo"
# >> 'text' is a TEXT_NODE containing "\n  bar\n"