Ruby:提取并操作部分提取的Nokogiri对象 需要“nokogiri” xml=DATA.read xml_nokogiri=nokogiri::xml.parse xml widgets=xml_nokogiri.xpath(“//Widget”) dates=widgets.map{| widget | widget.xpath(“//DateAdded”).text} 放日期 __结束__ 42 04/22/1989 29 02/05/2015
注释:Ruby:提取并操作部分提取的Nokogiri对象 需要“nokogiri” xml=DATA.read xml_nokogiri=nokogiri::xml.parse xml widgets=xml_nokogiri.xpath(“//Widget”) dates=widgets.map{| widget | widget.xpath(“//DateAdded”).text} 放日期 __结束__ 42 04/22/1989 29 02/05/2015,ruby,xpath,nokogiri,Ruby,Xpath,Nokogiri,注释: 这是一个我精心设计的例子,因为它非常不方便发布实际的代码,因为有太多的依赖关系。这样做是因为此代码在复制/粘贴时易于测试 小部件是一个Nokogiri::XML::NodeSet对象,它有两个Nokogiri::XML::Elements。每个都是与小部件标记相对应的xml片段 我打算再次使用xpath对这些片段进行操作,但是使用以/开头的xpath查询似乎再次从xml的根进行查询而不是单个片段 知道为什么吗?希望日期单独保留每个片段的标签 编辑:假设标记具有复杂的结构 相对寻址不实用(
Nokogiri::XML::NodeSet
对象,它有两个Nokogiri::XML::Element
s。每个都是与小部件标记相对应的xml片段/
开头的xpath
查询似乎再次从xml的根进行查询而不是单个片段xpath(“DateAdded”)
)//DateAdded
将为您提供相对XPath(任何嵌套的DateAdded
节点),以及简单的DateAdded
,无需前面的斜杠(直接子节点):
不幸的是,我没有包括一个方面:我不能使用绝对目标,因为标记非常复杂和动态。我已经更新了问题以反映它,无论如何谢谢你的时间。我不确定我是否理解你的评论<在此上下文中,code>DateAdded不是绝对值,而是相对于当前节点XPath。这里的当前节点显然是
widget
。我的意思是widgets(“//DateAdded”)
是相对的,widgets(“DateAdded”)
是绝对的。尽管您的解决方案似乎适用于此示例,但我的标记过于复杂和动态,无法使用绝对目标。而且,我很惊讶为什么相对的目标定位在那里不起作用。DateAdded
与//DateAdded
不同。如果在实际的XML输入中,DateAdded
不是Widget
的直接子项,则表达式将找不到任何内容//DateAdded
是最有可能需要的。适用的规范是XPath 1.0。Nokogiri使用libxml2,它只支持XPath1.0。抱歉,我吹毛求疵-1因为您没有编辑足够详细的问题xpath('.//DateAdded')
将在每次迭代期间在小部件下的任何级别搜索子体DateAdded
元素。
require 'nokogiri'
xml = DATA.read
xml_nokogiri = Nokogiri::XML.parse xml
widgets = xml_nokogiri.xpath("//Widget")
dates = widgets.map { |widget| widget.xpath("//DateAdded").text }
puts dates
__END__
<Widgets>
<Widget>
<Price>42</Price>
<DateAdded>04/22/1989</DateAdded>
</Widget>
<Widget>
<Price>29</Price>
<DateAdded>02/05/2015</DateAdded>
</Widget>
</Widgets>
- dates = widgets.map { |widget| widget.xpath("//DateAdded").text }
# for immediate children use 'DateAdded'
+ dates = widgets.map { |widget| widget.xpath("DateAdded").text }
# for nested elements use './/DateAdded'
+ dates = widgets.map { |widget| widget.xpath(".//DateAdded").text }
#⇒ [
# [0] "04/22/1989",
# [1] "02/05/2015"
#]