Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 使用Nokogiri从XML获取低级xpath_Ruby_Xpath_Nokogiri - Fatal编程技术网

Ruby 使用Nokogiri从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>

我试图将下面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
也许有人能帮我做这件事


感谢您的帮助。

您要选择的是“叶”节点。你可以这样做:

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