3

Ruby 1.9.3p385 を使用し、Nokogiri を使用して XML ファイルを解析します。私が使用している xpath バージョンはよくわかりませんが、v.2 構文ではなく、v.1 構文/関数に対応しています。

私はこのXMLファイルを持っています:

<root_tag>
  <middle_tag>
    <item_tag>
      <headline_1>
        <tag_1>Product title 1</tag_1>
      </headline_1>
      <headline_2>
        <tag_2>Product attribute 1</tag_2>
      </headline_2>
    </item_tag>
    <item_tag>
      <headline_1>
        <tag_1>Product title 2</tag_1>
      </headline_1>
      <headline_2>
        <tag_2>Product attribute 2</tag_2>
      </headline_2>
    </item_tag>
  </middle_tag>
</root_tag>

すべての製品を抽出したいので、次のコードを使用しています。

products = xml_file.xpath("/root_tag/middle_tag/item_tag/headline_1|/root_tag/middle_tag/item_tag/headline_2")

puts products.size # => 4

出力を見ると、次を使用します。

products.each_with_index do |product, i|
  puts "product #{i}:"
  puts product
end

あなたはこれを得る:

product 0:
<headline_1>
  <tag_1>Product title 1</tag_1>
</headline_1>
product 1:
<headline_2>
  <tag_2>Product attribute 1</tag_2>
</headline_2>
product 2:
<headline_1>
  <tag_1>Product title 2</tag_1>
</headline_1>
product 3:
<headline_2>
  <tag_2>Product attribute 2</tag_2>
</headline_2>

すべての一致を同じ結果に結合/マージするコードが必要です (したがって、products.size は 2 にする必要があります)。最終的な出力は次のようになります。

product 0:
<headline_1>
  <tag_1>Product title 1</tag_1>
</headline_1>
<headline_2>
  <tag_2>Product attribute 1</tag_2>
</headline_2>
product 1:
<headline_1>
  <tag_1>Product title 2</tag_1>
</headline_1>
<headline_2>
  <tag_2>Product attribute 2</tag_2>
</headline_2>

私はインターネット全体を見てきましたが、すべてのバリエーションがあります。

products = xml_file.xpath("/root_tag/middle_tag/item_tag/*[self::headline_1|self::headline_2]")

すべて同じ結果を出力するようです。

xpath で重要なポイントを見逃しているのでしょうか、それとも何か見落としているのでしょうか?

4

1 に答える 1

3

XPath は単純なシーケンスしか認識しないため、サブシーケンスのようなものはありません。各「製品」をいくつかの XML 要素にラップする必要があります。幸いなことに、すでにそのような要素 ( <item_tag/>) を取得しているため、コードはかなり単純です。

products = doc.xpath("(//item_tag")
products.each_with_index do |product, i|
  puts "product #{i}:"
  product.children.each do |line|
    puts line
  end
end

出力は次のとおりです(おそらくもう少しフォーマットが必要ですが、私はルビーに慣れていないため、それについてはお手伝いできません):

product 0:

<headline_1>
        <tag_1>Product title 1</tag_1>
      </headline_1>

<headline_2>
        <tag_2>Product attribute 1</tag_2>
      </headline_2>

product 1:

<headline_1>
        <tag_1>Product title 2</tag_1>
      </headline_1>

<headline_2>
        <tag_2>Product attribute 2</tag_2>
      </headline_2>

すべてのタグに対処するために、 を使用してコードをより柔軟にする<headline_n/>こともできます。//*[starts-with(local-name(), 'headline')]

于 2013-03-30T13:06:04.950 に答える