如何根据其中一个子元素的值删除XML元素?

时间:2012-12-11 17:49:51

标签: ruby xml nokogiri

我有一个xml元素,如下所示:

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

如何根据“ID”子项的值删除整个“Description”元素?

3 个答案:

答案 0 :(得分: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>

如您所见,删除了所需的描述节点。

答案 1 :(得分:0)

我个人会使用@JustinKo的解决方案,尽管有更简单的XPath:

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

然而,如果制作XPath并不是你的乐趣,而且编写Ruby就是这样,你可以更加依赖Ruby(如果效率稍差):

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

那说:

  • 找到名为<ID>
  • 的所有元素
  • 但是,只关注那些文字为"1234"
  • 的人
  • 将此映射为<Description>个节点(每个节点调用.parent的结果)
  • 然后在每个上面致电.remove

如果您知道只有一场比赛,您可以通过以下方式简化比赛:

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

答案 2 :(得分:-3)

要查找ID,请执行以下操作:

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

其中doc是通过加载xml文档创建的Nokogiri对象

要检查元素ID是否符合您的要求,请尝试:

if id == "1234"

从你的xml文件中,这应该返回true

最后删除整个描述用法:

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."