2017-04-24 20 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

あるLOCALサービス種別の価格を取得したいと思います:

rated_shipment.at('RateReplyDetails/Price').text 

おそらく私は次のようなことをすることができます:

if rated_shipment.at('RateReplyDetails/ServiceType').text == "LOCAL" 
    rated_shipment.at('RateReplyDetails/Price').text 

しかし、それを行うためのエレガントでクリーンな方法はありますか?

答えて

1

私のような何かをしたいです。

service_type.next_element.text # => "2.0" 

次の要素を見て、そのテキストを取得するのが簡単だと分かった後。 XPathの中に完全に

1

try、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"]'"LOCAL"に等しいテキストノードが含まれていると<ServiceType>ノードであるテキストを含むノードを返し< RateReplyDetails>ノードを探しXPathのセレクタです:

+0

セレクタでCSSの 'contains'を使用する場合は、サブ文字列の一致に注意してください。つまり、文字列のどこでも" INT "または" LOCAL "と一致し、誤って一致する可能性があります。 –

+0

私のテキストはそこで非常にユニークなので、これは私にとってはうまくいくはずです。私は答えとして最初の返答と正解を選択しましたが、これもうまくいくはずです。お返事ありがとうございました – user664859

+0

@theTinManあなたの思い出してくれてありがとう、実際に私はこの問題を知っています。私はこの答えを貼り付ける前に、前にやったことを試しましたが、失敗しました。今は 'text'を使う正しい方法を知っています。ありがとう。 –

0

rated_shipment.at('//RateReplyDetails[ServiceType="LOCAL"]/Price/text()').to_s 
# => "2.0" 

EDIT:

#!/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> 

それが仕事をして私のための証拠として

完全なコードを作業をdidntの

(出力は2.0)動作しない場合は、ファイルの内容がOPと一致しないためです。

+0

それは私のために働かなかった - 検索後に親に行く必要があった – user664859

関連する問題