我试图将下面XML中底层元素的所有惟一Xpath存储在一个数组中,但就像我在数组a中所做的那样,我存储的是所有XML,而不仅仅是Xpath本身。XML具有不同级别的Xpath。我的意思是,有些子元素只有两个祖先,而有些则不止一个。
这是我的代码。
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"中只存储唯一的路径,如下所示:
/items/item/name
/items/item/ppu
/items/item/batters/batter
/items/item/topping
也许有人能告诉我怎么做这件事。
谢谢你的帮助
您要选择的是"叶子"节点。你可以这样做:
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