2012-12-11 137 views
2

我有一個XML元素看起來像這樣:如何根據其子元素的值刪除XML元素?

<Description> 
    <ID>1234</ID> 
    <SubDescription> 
     <subID>4501</subID> 
    </SubDescription> 
    <SubDescription> 
     <subID>4502</subID> 
    </SubDescription> 
</Description> 

我怎樣才能根據其「ID」孩子的值刪除整個「說明」元素?

+0

[你嘗試過什麼(http://whathaveyoutried.com)? –

回答

2

您可以使用以下XPath來選擇包含值爲1234的ID節點描述節點:

//Description[./ID[text()='1234']] 

所以要刪除的節點,你可以這樣做:

doc.xpath("//Description[./ID[text()='1234']]").remove 

實施例:

require 'nokogiri' 

str = %q{ 
<root> 
    <Description> 
     <ID>2222</ID> 
     <SubDescription> 
     <subID>4501</subID> 
     </SubDescription> 
     <SubDescription> 
     <subID>4502</subID> 
     </SubDescription> 
    </Description> 
    <Description> 
     <ID>1234</ID> 
     <SubDescription> 
     <subID>4501</subID> 
     </SubDescription> 
     <SubDescription> 
     <subID>4502</subID> 
     </SubDescription> 
    </Description> 
</root> 
} 
doc = Nokogiri::XML(str) 
doc.xpath("//Description[./ID[text()='1234']]").remove 
puts doc 
#=> <root> 
#=> <Description> 
#=>  <ID>2222</ID> 
#=>  <SubDescription> 
#=>  <subID>4501</subID> 
#=>  </SubDescription> 
#=>  <SubDescription> 
#=>  <subID>4502</subID> 
#=>  </SubDescription> 
#=> </Description> 
#=></root> 

正如你可以看到,所需的描述節點被去除。

+0

這是一個不錯的解決方案。謝謝。 – drake10k

+1

注意:你的XPath可以做得更簡單(如果可能更「神奇」的似乎):'/ Description [ID ='1234']' – Phrogz

+0

謝謝@Phrogz,我不知道你能做到這一點。 –

-3

要查找ID做:

id = doc.xpath("//ID").text 

您想嘗試什麼樣的文檔是從加載XML文檔

要檢查創建的引入nokogiri對象,如果該元素的ID是:

if id == "1234" 

從XML文件本應返回true

最後刪除entir Ë描述】:

doc.xpath("//Description").remove 

你所要尋找的是這樣的:

doc = Nokogiri::XML(File.open("test.xml")) #create Nokogiri object from "test.xml" 
id = doc.xpath("//ID").text #this will be a string with the id 
doc.xpath("//Description").remove if id == "1234" #returns true with your xml document and remove the entire Description element." 
+1

-1'xpath'將返回一個NodeSet。如果文檔中有多個''節點,則所有節點都將返回,並且'text'將返回來自所有節點的內容,這將保持'id ==「1234」'不匹配。同樣,'xpath(「// Description」)。remove'將從文檔中刪除所有''節點。 –

0

我個人會用簡單的XPath通過@JustinKo使用該解決方案,雖然:

doc.xpath("//Description[ID='1234']").remove 

但是,如果各具特色XPath是不是你的有趣的想法,並寫Ruby是,你可以在紅寶石瘦更難(如果略少效率):

doc.css('ID').select{ |el| el.text=="1234" }.map(&:parent).each(&:remove) 

,上面寫着:

  • 找到所有命名爲的元素
  • 但削減下來做只是其文本是"1234"
  • 地圖這是<Description>節點(主叫每.parent的結果)
  • 然後調用每個那些.remove的人。

如果你知道,有永遠只能將是一場比賽,你可以把它用簡單:

doc.css('ID').find{ |el| el.text=="1234" }.parent.remove