应用于下面的(简化的)xml的代码获得了myanim1.swf的节点,正如预期的那样。我实际上想要myanim3.swf节点。我想说“获取带有属性名称= animationUrl的属性标记的第一个节点,但不要比一个孩子更深入”。我目前有一个解决方案,但我正在寻找一个更优雅的解决方案。
这是红宝石,对象是Nokogiri对象。我相信这是XPath搜索,但我有点不清楚它是否是Nokogiri的XPath味道。无论如何,感谢帮助,谢谢。
XML:
<blah>
<property name="overlays">
<array>
<object type="myType">
<property name="animationUrl" value="myanim1.swf"/>
</object>
<object type="myType">
<property name="animationUrl" value="myanim2.swf"/>
</object>
</array>
</property>
<property name="animationUrl" value="myanim3"/>
</property>
</blah>
CODE:
myNode = thisNode.search("property[name=animationUrl]").first.andand["value"]
答案 0 :(得分:2)
获取带有属性标记的第一个节点 使用属性name = animationUrl,但是 不要比一个孩子更深入
相对XPath表达式:
*[property/@name='animationUrl'][1]
这意味着:上下文节点的第一个子元素,其中至少有一个property
子元素的@name
属性等于'animationUrl'
绝对XPath表达式:
/*[property/@name='animationUrl']
这意味着:根元素至少有一个property
子元素,@name
属性等于'animationUrl'
/descendant::*[property/@name='animationUrl'][1]
这意味着:文档根目录的第一个后代元素,其中至少有一个property
子元素,@name
属性等于'animationUrl'
答案 1 :(得分:1)
我认为你需要这样的东西:
t.xpath("/blah/property[@name='animationUrl']")
答案 2 :(得分:1)
您需要使用at_xpath
以及对节点的绝对引用,这将指定您只想检索<blah><property>
深度的节点:
my_node = xml.at_xpath("/blah/property[@name='animationUrl']")
行动中:
require 'nokogiri'
thisNode = <<XML
<blah>
<property name="overlays">
<array>
<object type="myType">
<property name="animationUrl" value="myanim1.swf"/>
</object>
<object type="myType">
<property name="animationUrl" value="myanim2.swf"/>
</object>
</array>
</property>
<property name="animationUrl" value="myanim3"/>
</property>
</blah>
XML
xml=Nokogiri::XML(thisNode)
my_node = xml.at_xpath("/blah/property[@name='animationUrl']")
puts my_node #=> <property name="animationUrl" value="myanim3"/>
答案 3 :(得分:1)
如果你知道你想要的项目的深度,你可以这样做:
p d.at_xpath('//property[@name="animationUrl"][count(ancestor::*) = 1]')
但是,如果你知道深度,那么当然更容易做到:
p d.at_xpath('/*/property[@name="animationUrl"]')
如果你想要一个实际的广度优先搜索,找到任何深度最浅的项目:
虽然XPath允许您确定项目的深度(如上所示),但它不允许您对返回的NodeSet中的项目进行排序(这是您在纯XPath中需要执行的操作)。因此,我们将不得不求助于使用Ruby作为一般情况:
class Nokogiri::XML::Node
def at_shallowest_xpath( path )
xpath(path).sort_by{ |n| n.xpath 'count(ancestor::*)' }.first
end
end
d = Nokogiri::XML xml_source
puts d.at_shallowest_xpath('//property[@name="animationUrl"]')
#=> <property name="animationUrl" value="myanim3"/>
编辑:使用XPath查找深度,虽然很棘手,但是大约两倍(在我的机器上,使用此测试数据)要求Nokogiri找到元素的深度适合你。相反,使用这个:
class Nokogiri::XML::Node
def at_shallowest_xpath( path )
xpath(path).sort_by{ |n| n.ancestors.length }.first
end
end