使用Nokogiri从XML获取低级xpath



我试图将下面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

相关内容

  • 没有找到相关文章

最新更新