簡単な修正
の代わりにルートからのフル パスを使用して、単一の XPath を試してください//
。
例:
order = doc.at("/full/path/to/order[account_number=#{sap_account}]")
は//
ドキュメント全体をスキャンするため、パフォーマンスを向上させるために最初に取り除く必要があります。
本当に高速化したい場合は、SAX または Reader インターフェースを使用してください。
本当の速さ: Reader インターフェース
Reader インターフェース (および SAX) は、文書全体を DOM に構文解析する必要がないため、高速になります。一度に 1 つのノードでドキュメントを直線的に通過するだけです。これにより、利便性を犠牲にして速度が向上します (クエリやバックトラッキングはありません)。代わりに、必要な条件について各ノードをテストする必要があります。
Reader インターフェースを使用した例を次に示します (これは SAX よりも少し単純です)。次のファイルがあるとします。
<orders>
<order account_number="1">
<item>Foo</item>
</order>
<order account_number="2">
<item>Bar</item>
</order>
<order account_number="3">
<item>Baz</item>
</order>
</orders>
<item>
のの順に をaccount_number
取り出したいとしましょう2
。コードは次のとおりです。
require 'nokogiri'
filename = ARGV[0]
sap_account = "2"
File.open(filename) do |file|
Nokogiri::XML::Reader.from_io(file).each do |node|
if node.name == 'order' and node.attribute('account_number') == sap_account
puts node.inner_xml
end
end
end
出力:
<item>Bar</item>