Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.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/Xpath浅层搜索_Ruby_Search_Xpath_Nokogiri - Fatal编程技术网

Ruby/Nokogiri/Xpath浅层搜索

Ruby/Nokogiri/Xpath浅层搜索,ruby,search,xpath,nokogiri,Ruby,Search,Xpath,Nokogiri,下面应用于简化xml的代码使我获得了myanim1.swf的节点,正如预期的那样。实际上,我想要一个带有myanim3.swf的节点。我想说的是,获取第一个带有属性名=animationUrl的属性标记的节点,但不要深入到一个子节点。我目前有一个解决方案,但我正在寻找一个更优雅的解决方案 这是ruby,对象是Nokogiri对象。我相信这是XPath搜索,但我有点不清楚这是否是Nokogiri的XPath风格。无论如何,谢谢你的帮助 XML: 我想你需要这样的东西: t.xpath("/blah

下面应用于简化xml的代码使我获得了myanim1.swf的节点,正如预期的那样。实际上,我想要一个带有myanim3.swf的节点。我想说的是,获取第一个带有属性名=animationUrl的属性标记的节点,但不要深入到一个子节点。我目前有一个解决方案,但我正在寻找一个更优雅的解决方案

这是ruby,对象是Nokogiri对象。我相信这是XPath搜索,但我有点不清楚这是否是Nokogiri的XPath风格。无论如何,谢谢你的帮助

XML:


我想你需要这样的东西:

t.xpath("/blah/property[@name='animationUrl']")

我想你需要这样的东西:

t.xpath("/blah/property[@name='animationUrl']")
您需要使用at_xpath以及对节点的绝对引用,这将指定您只希望在以下深度检索节点:

在行动中:

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"/>
您需要使用at_xpath以及对节点的绝对引用,这将指定您只希望在以下深度检索节点:

在行动中:

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"/>

如果您知道所需物品的深度,可以执行以下操作:

p d.at_xpath('//property[@name="animationUrl"][count(ancestor::*) = 1]')
但是,如果您知道深度,那么当然更容易做到:

p d.at_xpath('/*/property[@name="animationUrl"]')
如果您希望进行实际的广度优先搜索,在任何深度都能找到最浅的项目:

虽然XPath允许您如上所示确定项目的深度,但它不允许您在返回的节点集中对项目进行排序,而这正是纯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"/>

如果您知道所需物品的深度,可以执行以下操作:

p d.at_xpath('//property[@name="animationUrl"][count(ancestor::*) = 1]')
但是,如果您知道深度,那么当然更容易做到:

p d.at_xpath('/*/property[@name="animationUrl"]')
如果您希望进行实际的广度优先搜索,在任何深度都能找到最浅的项目:

虽然XPath允许您如上所示确定项目的深度,但它不允许您在返回的节点集中对项目进行排序,而这正是纯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"/>
获取带有属性标记的第一个节点 属性名称=animationUrl,但 不要超过一个孩子

相对XPath表达式:

*[property/@name='animationUrl'][1]
这意味着:上下文节点的第一个子元素至少有一个@name属性等于“animationUrl”的属性子元素

绝对XPath表达式:

/*[property/@name='animationUrl']
这意味着:根元素至少有一个@name属性等于'animationUrl'的属性子元素

这意味着:文档根的第一个子元素至少有一个属性子元素@name属性等于“animationUrl”

获取带有属性标记的第一个节点 属性名称=animationUrl,但 不要超过一个孩子

相对XPath表达式:

*[property/@name='animationUrl'][1]
这意味着:上下文节点的第一个子元素至少有一个@name属性等于“animationUrl”的属性子元素

绝对XPath表达式:

/*[property/@name='animationUrl']
这意味着:根元素至少有一个@name属性等于'animationUrl'的属性子元素


这意味着:documentroot的第一个子元素至少有一个property子元素,其@name属性等于'animationUrl'

我认为您误解了OP的意图。他只想在根的子级提取一个节点。他不需要计算深度。@MarkThomas Ack,你说得对。我完全没听懂这些话,但不要说得比一个孩子更深。我把浅层搜索误解为广度优先,先找到最浅的。哦,答案的上半部分仍然有效,至少:我认为你误读了OP的意图。他只想在根的子级提取一个节点。他不需要计算深度。@MarkThomas Ack,你说得对。我完全没听懂这些话,但不要说得比一个孩子更深。我把浅层搜索误解为广度优先,先找到最浅的。哦,答案的上半部分仍然有效,至少:Nokogiri的XPath风格?Nokogiri使用libxml2,这是一个标准的XML解析器?Nokogiri使用libxml2,这是一个标准的XML解析器。你可以用在。Nokogiri将做正确的事情。使用at将返回指定级别上所有出现的具有animationUrl的对象。at_xpath将只返回op所查找的第一个实例。您不必使用at_xpath。你可以用在。Nokogiri将做正确的事情。使用at将返回指定级别上所有出现的具有animationUrl的对象。at_xpath将只返回op所寻找的第一个实例。