XPath の背後にあるアイデアの 1 つは、ディスク ディレクトリと同様に DOM をナビゲートできるようにすることです。
require 'hpricot'
xml = <<EOT
<rss>
<channel>
<item>
<title>Book1</title>
<pubDate>march 1 2010</pubDate>
<author>Bob</author>
</item>
<item>
<title>book2</title>
<pubDate>october 4 2009</pubDate>
<author>Bill</author>
</item>
<item>
<title>book3</title>
<pubDate>June 5 2010</pubDate>
<author>Steve</author>
</item>
<item>
<title>Book4</title>
<pubDate>march 1 2010</pubDate>
<author>Bob</author>
</item>
</channel>
</rss>
EOT
doc = Hpricot(xml)
titles = (doc / '//author[text()="Bob"]/../title' )
titles # => #<Hpricot::Elements[{elem <title> "Book1" </title>}, {elem <title> "Book4" </title>}]>
つまり、「ボブの本をすべて見つけてから、1 レベル上を調べて、タイトル タグを見つける」ということです。
すべてのオカレンスを取得することをテストするために、"Bob" による別の本を追加しました。
Bob の本を含むアイテムを取得するには、レベルを 1 つ上に戻します。
items = (doc / '//author[text()="Bob"]/..' )
puts items # => nil
# >> <item>
# >> <title>Book1</title>
# >> <pubdate>march 1 2010</pubdate>
# >> <author>Bob</author>
# >> </item>
# >> <item>
# >> <title>Book4</title>
# >> <pubdate>march 1 2010</pubdate>
# >> <author>Bob</author>
# >> </item>
私はまた、何をしているのかを理解しました(doc % :rss % :channel / :item)
。これは、検索をネストして、折り返し括弧を除いたものと同等であり、Hpricot-ese ではこれらはすべて同じである必要があります。
(doc % :rss % :channel / :item).size # => 4
(((doc % :rss) % :channel) / :item).size # => 4
(doc / '//rss/channel/item').size # => 4
(doc / 'rss channel item').size # => 4
'//rss/channel/item'
通常、XPath アクセサー'rss channel item'
は CSS アクセサーとして表示されるため、メンテナンスと明確化のためにこれらの形式を使用することをお勧めします。