Nokogiri ::基于另一个XML属性值的XML解析值
问题描述:
使用Nokogiri :: XML如何基于另一个属性检索属性的值?Nokogiri ::基于另一个XML属性值的XML解析值
XML文件:
<RateReplyDetails>
<ServiceType>INT</ServiceType>
<Price>1.0</Price>
</RateReplyDetails>
<RateReplyDetails>
<ServiceType>LOCAL</ServiceType>
<Price>2.0</Price>
</RateReplyDetails>
而且我想检索本地服务类型是2.0
我可以采取的值,而不任何与此条件的价格:
rated_shipment.at('RateReplyDetails/Price').text
而且可能我可以这样做:
if rated_shipment.at('RateReplyDetails/ServiceType').text == "LOCAL"
rated_shipment.at('RateReplyDetails/Price').text
但是,有没有这样做的优雅和干净的方式?
答
我会做这样的事情:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<xml>
<RateReplyDetails>
<ServiceType>INT</ServiceType>
<Price>1.0</Price>
</RateReplyDetails>
<RateReplyDetails>
<ServiceType>LOCAL</ServiceType>
<Price>2.0</Price>
</RateReplyDetails>
</xml>
EOT
service_type = doc.at('//RateReplyDetails/*[text() = "LOCAL"]')
service_type.name # => "ServiceType"
'//RateReplyDetails/*[text() = "LOCAL"]'
是一个XPath选择,以查找包含相同文本节点"LOCAL"
,并返回包含文本,这是<ServiceType>
节点的节点的节点< RateReplyDetails>
。
service_type.next_element.text # => "2.0"
一旦我们发现很容易查看下一个元素并获取其文本。
答
尝试,content
是xml内容字符串。
doc = Nokogiri::HTML(content)
doc.at('servicetype:contains("INT")').next_element.content
[16] pry(main)>
doc.at('servicetype:contains("INT")').next_element.content
=> "1.0"
[17] pry(main)>
doc.at('servicetype:contains("LOCAL")').next_element.content
=> "2.0"
我已测试它,它的工作。
答
完全XPath中:
rated_shipment.at('//RateReplyDetails[ServiceType="LOCAL"]/Price/text()').to_s
# => "2.0"
编辑:
它没有工作对我来说
的完整代码以证明它的工作:
#!/usr/bin/env ruby
require 'nokogiri'
rated_shipment = Nokogiri::XML(DATA)
puts rated_shipment.at('//RateReplyDetails[ServiceType="LOCAL"]/Price/text()').to_s
__END__
<xml>
<RateReplyDetails>
<ServiceType>INT</ServiceType>
<Price>1.0</Price>
</RateReplyDetails>
<RateReplyDetails>
<ServiceType>LOCAL</ServiceType>
<Price>2.0</Price>
</RateReplyDetails>
</xml>
(输出2.0
。)如果它不起作用,那是因为你的文件内容与你的OP不匹配。
+0
它没有为我工作 - 必须在搜索后去父母 – user664859
在选择器中使用CSS'contains'要小心,因为它是子字符串匹配,这意味着它将在字符串中的任何位置匹配“INT”或“LOCAL”,可能会导致错误匹配。 –
这应该也适用于我,因为我的文本在那里非常独特。我选择了第一个回答正确的答案作为答案,但这也应该起作用。谢谢各位 – user664859
@theTinMan感谢您的提醒,其实我知道这个问题,在我粘贴这个答案之前,我尝试了你之前做过的方式,但是失败了,现在我知道现在使用'text'的正确方法。谢谢。 –