在使用XPath读取XML方面已经写了很多关于Nokogiri的文章。但是,如何在包含XPath引用的XML中使用Nokogiri。
在本例中,xml包含一个XPath引用:
<elements>
<element>
<location>
<longitude>...
<latitude>...
</location>
</element>
<element>
<location reference="../../element/location"/>
</element>
</elements>
因为这两个位置元素是相等的,所以只详细描述了第一个元素。第二个只是引用了第一个。
使用Nokogiri,xml.xpath('//location')按预期返回两个节点实例。第一个节点包含所有子节点。第二个仅作为第二个节点实例的属性的引用。
好的,假设我想请求所有经度值,我将执行xml.xpath('//location/longitude').这只返回一个节点实例。但是,由于实际上有两个类型为“经度”的元素,我希望接收两个节点实例,期望Nokogiri解析XPath引用.
我如何通过Nokogiri实现这一点?
发布于 2011-01-29 19:07:40
您可以收集具有实际值的位置节点(非引用节点),然后单独收集所有引用,如下所示:
require 'nokogiri'
xml = <<End
<elements>
<element>
<location>
<longitude>45</longitude>
<latitude>-70</latitude>
</location>
</element>
<element>
<location reference="../../element/location"/>
</element>
</element>
End
doc = Nokogiri::XML(xml)
#Collect all the explicit longitudes
longitudes = doc.search('//location[not(@reference)]/longitude').map(&:text)
#Follow references to longitudes
doc.search('//location[@reference]').each do |location|
reference = location.attribute('reference')
longitudes << location.xpath("#{reference}/longitude").text
end
puts longitudes #=> ["45", "45"]
您可以在此技术基础上提取任何您想要的信息。
发布于 2011-01-29 17:46:17
您还没有提供任何线索,第二个location
元素如何引用第一个.
即使这个机制是已知的longitude
,并且我们能够在XPath表达式中指定它来选择引用的location
元素,选择的两个location
节点将是相同的。
当计算一个XPath表达式时,它总是返回一组节点--也就是说,如果同一个节点不止一次在选择结果中被表示一次--一个集合不包含重复的项。
这就是为什么longitude
元素在选择中只显示一次的原因,即使它被选中了两次。
这里是一个例子,;
<a>
<b>
<c/>
</b>
</a>
XPath表达式
/a/* x/c/.
只选择一个元素 b
--而不是两个相同的元素b
。
https://stackoverflow.com/questions/4836521
复制相似问题