2017-04-24 90 views
0

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

但是,有沒有這樣做的優雅和乾淨的方式?

回答

1

我會做這樣的事情:

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" 

一旦我們發現很容易查看下一個元素並獲取其文本。

1

嘗試,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" 

我已測試它,它的工作。

+0

在選擇器中使用CSS'contains'要小心,因爲它是子字符串匹配,這意味着它將在字符串中的任何位置匹配「INT」或「LOCAL」,可能會導致錯誤匹配。 –

+0

這應該也適用於我,因爲我的文本在那裏非常獨特。我選擇了第一個回答正確的答案作爲答案,但這也應該起作用。謝謝各位 – user664859

+0

@theTinMan感謝您的提醒,其實我知道這個問題,在我粘貼這個答案之前,我嘗試了你之前做過的方式,但是失敗了,現在我知道現在使用'text'的正確方法。謝謝。 –

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