我正在尝试在数组中存储下面XML中低级元素的所有唯一Xpath,但就像我在数组中一样,存储所有XML,而不仅仅是Xpath本身。 XML具有不同级别的Xpath。我的意思是,一些子元素只有2个祖先,而其他元素不止一个。
这是我的代码。
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
我想在数组“a”中存储唯一的xpath,如下所示:
/items/item/name
/items/item/ppu
/items/item/batters/batter
/items/item/topping
也许有人可以帮我解决这个问题。
感谢您的帮助。
答案 0 :(得分:2)
您想要选择的是&#34; leaf&#34;节点。你可以这样做:
doc.xpath("//*[not(*)]")
这意味着&#34;选择所有不包含元素的元素&#34;。
如果您需要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