Nokogiri::XML 根据另一个 XML 属性的值解析值
Nokogiri::XML parse value based on another XML attribute's value
如何使用 Nokogiri::XML 检索基于另一个属性的属性值?
XML 文件:
<RateReplyDetails>
<ServiceType>INT</ServiceType>
<Price>1.0</Price>
</RateReplyDetails>
<RateReplyDetails>
<ServiceType>LOCAL</ServiceType>
<Price>2.0</Price>
</RateReplyDetails>
我想检索 LOCAL ServiceType 的价格,它是 2.0
我可以无条件地使用这个值:
rated_shipment.at('RateReplyDetails/Price').text
也许我可以做类似的事情:
if rated_shipment.at('RateReplyDetails/ServiceType').text == "LOCAL"
rated_shipment.at('RateReplyDetails/Price').text
但是有什么优雅干净的方法吗?
试一下,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"
我已经测试过了,可以用了。
我会这样做:
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"
的文本节点的 < RateReplyDetails>
节点和包含文本的节点 returns,即<ServiceType>
节点。
service_type.next_element.text # => "2.0"
一旦我们发现很容易查看下一个元素并获取其文本。
完全在 XPath 中:
rated_shipment.at('//RateReplyDetails[ServiceType="LOCAL"]/Price/text()').to_s
# => "2.0"
编辑:
it didnt work for me
证明它确实有效的完整代码:
#!/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不匹配。
如何使用 Nokogiri::XML 检索基于另一个属性的属性值?
XML 文件:
<RateReplyDetails>
<ServiceType>INT</ServiceType>
<Price>1.0</Price>
</RateReplyDetails>
<RateReplyDetails>
<ServiceType>LOCAL</ServiceType>
<Price>2.0</Price>
</RateReplyDetails>
我想检索 LOCAL ServiceType 的价格,它是 2.0
我可以无条件地使用这个值:
rated_shipment.at('RateReplyDetails/Price').text
也许我可以做类似的事情:
if rated_shipment.at('RateReplyDetails/ServiceType').text == "LOCAL"
rated_shipment.at('RateReplyDetails/Price').text
但是有什么优雅干净的方法吗?
试一下,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"
我已经测试过了,可以用了。
我会这样做:
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"
的文本节点的 < RateReplyDetails>
节点和包含文本的节点 returns,即<ServiceType>
节点。
service_type.next_element.text # => "2.0"
一旦我们发现很容易查看下一个元素并获取其文本。
完全在 XPath 中:
rated_shipment.at('//RateReplyDetails[ServiceType="LOCAL"]/Price/text()').to_s
# => "2.0"
编辑:
it didnt work for me
证明它确实有效的完整代码:
#!/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不匹配。