Ruby Nokogiri XML.children除了返回实际元素外还返回格式化元素。如何避免这种情况?

Ruby Nokogiri XML.children除了返回实际元素外还返回格式化元素。如何避免这种情况?,ruby,ruby-on-rails-3,nokogiri,Ruby,Ruby On Rails 3,Nokogiri,我有以下XML: <attributes> <intelligence>27</intelligence> <memory>21</memory> <charisma>17</charisma> <perception>17</perception> <willpower>17</willpower> </attribu

我有以下XML:

<attributes>
    <intelligence>27</intelligence>
    <memory>21</memory>
    <charisma>17</charisma>
    <perception>17</perception>
    <willpower>17</willpower>
</attributes>
当我尝试此代码时:

def get_attributes(api)
  attributes = []
  api.xpath("//attributes").children.each do |attribute|
    name = attribute.name.tr('^A-Za-z0-9', '')
    text = attribute.text
    attributes << "#{name}: #{text}"
  end
  attributes
end
Nokogiri中是否有一种方法可以跳过这些“仅格式化”子项?或者我必须只手动遍历奇数元素吗


我希望
api.xpath(“//attributes”).children
导航实际的子对象,而不是格式文本

我认为简短的答案是“不”。但是,您可以轻松地执行以下操作:

if attribute.element?
    name = attribute.name.tr('^A-Za-z0-9', '')
    text = attribute.text
    attributes << "#{name}: #{text}"
end
'intelligence: %02d, memory: %02d, charisma: %02d, perception: %02d, willpower: %02d' % doc.at('attributes').children.map(&:text)
=> "intelligence: 27, memory: 21, charisma: 17, perception: 17, willpower: 17"

如果您只需要子节点的文本节点,请使用:

require 'nokogiri'
require 'pp'

doc = Nokogiri::HTML(<<EOT)
<attributes>
    <intelligence>27</intelligence>
    <memory>21</memory>
    <charisma>17</charisma>
    <perception>17</perception>
    <willpower>17</willpower>
</attributes>
EOT

doc.at('attributes').children.map(&:text)
从那里,您可以轻松地执行以下操作:

if attribute.element?
    name = attribute.name.tr('^A-Za-z0-9', '')
    text = attribute.text
    attributes << "#{name}: #{text}"
end
'intelligence: %02d, memory: %02d, charisma: %02d, perception: %02d, willpower: %02d' % doc.at('attributes').children.map(&:text)
=> "intelligence: 27, memory: 21, charisma: 17, perception: 17, willpower: 17"
如果您希望它更加结构化,可以执行以下操作:

doc.at('attributes').children.each_with_object({}){ |o,h| h[o.name] = o.text }
=> {"intelligence"=>"27", "memory"=>"21", "charisma"=>"17", "perception"=>"17", "willpower"=>"17"}
或:


doc.at('attributes')。子项
=> [#, #, #, #, #]
该方法将返回目标节点的所有子节点,包括文本节点。如果只需要所有元素节点子节点,可以在XPath查询中使用
*
指定它:

def attributes(api)
  api.xpath('//attributes/*').each_with_object([]) do |n, ary|
    ary << "#{n.name}: #{n.text}"
  end
end
def属性(api) xpath('//attributes/*')。带有对象([])的每个对象都是|
使用你的第一行代码,我仍然得到一个回车字符元素(但它非常接近):
{:text=>“\n”,“intelligence=>”20“,:memory=>”25“,:charisma=>”23“,:perception=>”16“,:willpower=>”15“}
如果你得到回车,那么就有错误/缺失的地方。您可以看到上面的代码没有做任何特殊的事情,CR也不存在。文本节点存在于子节点之外,但不会被返回。Nokogiri当前处于v1.5.6。如果您不在最新版本上,您可以尝试使用
gem update nokogiri
更新它。我使用的是最新版本-在我的实际XML中似乎有一个元素,它被视为具有对象
text=>“\n”
我认为这与我的源代码有关——尽管在这种情况下知道如何避免它会很好。
doc.at('attributes').children.each_with_object({}){ |o,h| h[o.name] = o.text }
=> {"intelligence"=>"27", "memory"=>"21", "charisma"=>"17", "perception"=>"17", "willpower"=>"17"}
doc.at('attributes').children.each_with_object({}){ |o,h| h[o.name.to_sym] = o.text }
=> {:intelligence=>"27", :memory=>"21", :charisma=>"17", :perception=>"17", :willpower=>"17"}
doc.at('attributes').children
=> [#<Nokogiri::XML::Element:0x3fc3245fb8fc name="intelligence" children=[#<Nokogiri::XML::Text:0x3fc3245fb6f4 "27">]>, #<Nokogiri::XML::Element:0x3fc3245fb4ec name="memory" children=[#<Nokogiri::XML::Text:0x3fc3245fb2e4 "21">]>, #<Nokogiri::XML::Element:0x3fc3245fb0dc name="charisma" children=[#<Nokogiri::XML::Text:0x3fc3245faed4 "17">]>, #<Nokogiri::XML::Element:0x3fc3245fecb4 name="perception" children=[#<Nokogiri::XML::Text:0x3fc3245feaac "17">]>, #<Nokogiri::XML::Element:0x3fc3245fe8a4 name="willpower" children=[#<Nokogiri::XML::Text:0x3fc3245fe69c "17">]>]
def attributes(api)
  api.xpath('//attributes/*').each_with_object([]) do |n, ary|
    ary << "#{n.name}: #{n.text}"
  end
end