2014-09-25 79 views
0

在解析XML元素,找到属性名称值我有以下XML:不能与引入nokogiri

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

我需要保存“标题”字段的值,只有属性LANG = EN-US。所以我试图让“EN思科IPS 4240传感器”具有以下内容:

doc.search("//title[@lang='en-US']") 

返回

=> [] 

请指教如何正确获取这些字段的值。

回答

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" ] 
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获得在嵌入式/ 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,您不需要。

此找到所有匹配<title xml:lang="en-US">标签的文本:

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会谈是重要的阅读。