我有以下XML:
<cpe-list>
<cpe-item name="cpe:/a:1024cms:1024_cms:0.7">
<title xml:lang="en-US">1024cms.org 1024 CMS 0.7</title>
<meta:item-metadata nvd-id="121218" status="DRAFT" modification-date="2010-12-14T19:38:32.197Z"/>
</cpe-item>
<cpe-item name="cpe:/a:1024cms:1024_cms:1.2.5">
<title xml:lang="en-US">1024cms.org 1024 CMS 1.2.5</title>
<meta:item-metadata nvd-id="121219" status="DRAFT" modification-date="2010-12-14T19:38:32.240Z"/>
</cpe-item>
<cpe-item name="cpe:/h:cisco:ips_4240">
<title xml:lang="ja-JP">JAPAN IPS 4240 Sensor</title>
<title xml:lang="en-US">EN Cisco IPS 4240 Sensor</title>
<meta:item-metadata nvd-id="138255" status="DRAFT" modification-date="2011-01-12T14:36:11.990Z"/>
</cpe-item>
</cpe-list>
我需要保存'title'字段的值,只使用lang = en-US属性。所以我试图通过以下方式获得“EN Cisco IPS 4240传感器”:
doc.search("//title[@lang='en-US']")
返回
=> []
请告知如何正确获取这些字段的值。
答案 0 :(得分:2)
该属性是命名空间(它是xml:lang
,而不仅仅是lang
),因此您需要在搜索中包含命名空间:
doc.search("//title[@xml:lang='en-US']")
我只是在本地尝试了这个,它返回所有三个<title xml:lang="en-US">
元素。要获取每个文本,只需在每个文本上调用text
,或使用map
:
doc.search("//title[@xml:lang='en-US']").map(&:text)
# => [ "1024cms.org 1024 CMS 0.7",
# "1024cms.org 1024 CMS 1.2.5",
# "EN Cisco IPS 4240 Sensor" ]
答案 1 :(得分:0)
Nokogiri支持CSS选择器,所以我会这样做:
require 'nokogiri'
xml = '<cpe-list>
<cpe-item name="cpe:/a:1024cms:1024_cms:0.7">
<title xml:lang="en-US">1024cms.org 1024 CMS 0.7</title>
<meta:item-metadata nvd-id="121218" status="DRAFT" modification-date="2010-12-14T19:38:32.197Z"/>
</cpe-item>
<cpe-item name="cpe:/a:1024cms:1024_cms:1.2.5">
<title xml:lang="en-US">1024cms.org 1024 CMS 1.2.5</title>
<meta:item-metadata nvd-id="121219" status="DRAFT" modification-date="2010-12-14T19:38:32.240Z"/>
</cpe-item>
<cpe-item name="cpe:/h:cisco:ips_4240">
<title xml:lang="ja-JP">JAPAN IPS 4240 Sensor</title>
<title xml:lang="en-US">EN Cisco IPS 4240 Sensor</title>
<meta:item-metadata nvd-id="138255" status="DRAFT" modification-date="2011-01-12T14:36:11.990Z"/>
</cpe-item>
</cpe-list>
'
doc = Nokogiri::XML(xml)
doc.at('title:nth-of-type(2)').to_xml # => "<title xml:lang=\"en-US\">EN Cisco IPS 4240 Sensor</title>"
CSS会产生一个非常清晰的选择器。或者,XPath可以这样做:
doc.at('//title[2]').to_xml # => "<title xml:lang=\"en-US\">EN Cisco IPS 4240 Sensor</title>"
在任何一种情况下,使用text
来获取嵌入/子文本节点:
doc.at('title:nth-of-type(2)').text # => "EN Cisco IPS 4240 Sensor"
doc.at('//title[2]').text # => "EN Cisco IPS 4240 Sensor"
在任何一种情况下,您都可以使用CSS和/或XPath的功能将选择器扩展为更明确,以便在需要时查看参数及其值,但是,根据您的示例XML,您不需要&#39;吨。
这会找到所有匹配的<title xml:lang="en-US">
标记&#39;文本:
doc.search('title[xml|lang="en-US"]').map(&:text) # => ["1024cms.org 1024 CMS 0.7", "1024cms.org 1024 CMS 1.2.5", "EN Cisco IPS 4240 Sensor"]
Nokogiri "Searching an HTML / XML Document" tutorial讨论了在&#34;命名空间&#34;中处理命名空间的问题。部分并且是重要的阅读。