Ruby 使用Nokogiri从XML获取低级xpath
我试图将下面XML中低级元素的所有唯一Xpath存储在一个数组中,但就像我在数组a中所做的那样,存储的是所有XML,而不仅仅是Xpath本身。XML具有不同级别的Xpath。我的意思是,有些子元素只有两个祖先,而有些子元素不止一个 这是我的密码Ruby 使用Nokogiri从XML获取低级xpath,ruby,xpath,nokogiri,Ruby,Xpath,Nokogiri,我试图将下面XML中低级元素的所有唯一Xpath存储在一个数组中,但就像我在数组a中所做的那样,存储的是所有XML,而不仅仅是Xpath本身。XML具有不同级别的Xpath。我的意思是,有些子元素只有两个祖先,而有些子元素不止一个 这是我的密码 require 'nokogiri' doc = Nokogiri::XML(<<EOT) <?xml version="1.0" encoding="UTF-8"?> <items> <item>
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<?xml version="1.0" encoding="UTF-8"?>
<items>
<item>
<name>Cake</name>
<ppu>0.55</ppu>
<batters>
<batter>Regular</batter>
<batter>Chocolate</batter>
<batter>Blueberry</batter>
<batter>Devil's Food</batter>
</batters>
<topping>None</topping>
<topping>Glazed</topping>
<topping>Sugar</topping>
<topping>Powdered Sugar</topping>
<topping>Chocolate with Sprinkles</topping>
<topping>Chocolate</topping>
<topping>Maple</topping>
</item>
<item>
<name>Raised</name>
<ppu>0.55</ppu>
<batters>
<batter>Regular</batter>
</batters>
<topping>None</topping>
<topping>Glazed</topping>
<topping>Sugar</topping>
<topping>Chocolate</topping>
<topping>Maple</topping>
</item>
</items>
EOT
a = []
a = doc.xpath("//*")
puts a
也许有人能帮我做这件事
感谢您的帮助。您要选择的是“叶”节点。你可以这样做:
doc.xpath("//*[not(*)]")
这意味着“选择所有不包含元素的元素”
如果需要XPath,则需要在每个节点上调用.path
。但是Nokogiri提供的路径有明确的位置(例如/items/item[2]/topping[4]
),因此您必须应用正则表达式来删除它们,然后使用uniq
删除重复的路径:
doc.xpath("//*[not(*)]").map {|leaf| leaf.path.gsub(/\[.*?\]/, '') }.uniq
输出:
/items/item/name
/items/item/ppu
/items/item/batters/batter
/items/item/topping
你到底想储存什么?XPath本身还是元素的内容。回答得很好。谢谢。答案中混合了几个概念(ruby方法、正则表达式、xpath等)。我不知道正确的名称是叶节点。谢谢你的澄清。你知道一个很好的链接在哪里可以看到Xpath的选项吗?我不知道您使用的选项“[非(*)]”的存在和意义。谢谢Againcate xpath表达式。@Zurix有一个很好的W3Schools。具体地说,
[]
是一个进一步约束表达式的谓词,not()
是一个返回布尔值的XPath函数,在本例中,如果有任何子元素(*
),它将返回false。我不确定它是否有用,但您可能需要考虑XPath/*[not(*)]
相当于Ruby伪代码元素。选择{| el | el.child_elements.empty?}
非常感谢Mark提供的解释和帮助。非常感激。
/items/item/name
/items/item/ppu
/items/item/batters/batter
/items/item/topping