2013-03-30 65 views
3

我使用Ruby 1.9.3p385,並使用Nokogiri來解析XML文件。不太確定我使用的是哪個xpath版本,但它確實對v.1語法/函數做出響應,而不是v.2語法。xpath挑戰:如何將多個結果合併爲一個結果

我有這個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中的一些重要點,還是我忽略了一些東西?

+0

請編輯您的XML,使我們能夠理解您的預期輸出應該是什麼樣的(例如,將「產品標題」更改爲不同的字符串)。然後,添加預期的輸出(不計算結果)。您正在使用哪種XPath引擎,它支持哪種XPath版本?不可能以現在的方式回答你的問題,而無需猜測。 –

+0

Hi @JensErat。非常感謝您的回覆。如果我遺漏了重要信息,我很抱歉,現在我已經在您的指示後更新了我的問題。我現在擁有這些嗎? – JohnSmith1976

+0

現在問題看起來完全沒問題! –

回答

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 

輸出是(可能需要一些更多的格式,但我不習慣Ruby和不能幫助你與):

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')]使代碼更靈活。

+0

這是完美的。靈活的xpath表達式適用於我的開箱即用。我的測試數據中的其中一個文件具有這樣的路徑:_/item_tag_something/middle_tag/item_tag(headline_1 | headline_2)_,這意味着_item_tag_something_返回TRUE,因此被視爲產品。但是我會查看xpath函數庫,看看我能否讓表達式容忍一點。 – JohnSmith1976

相關問題