I have an xml element looking something like this:
<Description>
<ID>1234</ID>
<SubDescription>
<subID>4501</subID>
</SubDescription>
<SubDescription>
<subID>4502</subID>
</SubDescription>
</Description>
How can I delete the entire "Description" element according to the value of its "ID" child?
You can use the following xpath to select Description nodes that contain an ID node with value 1234:
//Description[./ID[text()='1234']]
So to remove the node, you can do:
doc.xpath("//Description[./ID[text()='1234']]").remove
Example:
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>
As you can see, the desired description node is removed.
I personally would use the solution by @JustinKo, albeit with the simpler XPath:
doc.xpath("//Description[ID='1234']").remove
However, if crafting XPath isn't your idea of fun, and writing Ruby is, you can lean on Ruby harder (if slightly less efficiently):
doc.css('ID').select{ |el| el.text=="1234" }.map(&:parent).each(&:remove)
That says:
<ID>
"1234"
<Description>
nodes (the result of calling .parent
on each) .remove
on each of those. If you know that there's only ever going to be one match, you can make it simpler with:
doc.css('ID').find{ |el| el.text=="1234" }.parent.remove
To find the ID do:
id = doc.xpath("//ID").text
where doc is the Nokogiri object created from loading the xml document
To check if the element id is what you want try:
if id == "1234"
From your xml file this should return true
Finally to remove the entire Description use:
doc.xpath("//Description").remove
What you're looking for is this:
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."
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.