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

Ruby 如何根据一个子元素的值删除XML元素?,ruby,xml,nokogiri,Ruby,Xml,Nokogiri,我有一个xml元素,看起来像这样: <Description> <ID>1234</ID> <SubDescription> <subID>4501</subID> </SubDescription> <SubDescription> <subID>4502</subID> </SubDescript

我有一个xml元素,看起来像这样:

<Description>
    <ID>1234</ID>
    <SubDescription>
        <subID>4501</subID>
    </SubDescription>
    <SubDescription>
        <subID>4502</subID>
    </SubDescription>
</Description>
如何根据ID子元素的值删除整个描述元素?

要查找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."
要查找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."

可以使用以下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>

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

您可以使用以下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>

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

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

doc.xpath("//Description[ID='1234']").remove
但是,如果制作XPath不是您的乐趣所在,而编写Ruby则是如此,那么您可以更努力地使用Ruby,但效率会稍低一些:

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

查找所有名为 但是,如果文本是1234,那么就把它删减 将此映射为每个节点上调用.parent的结果 然后打电话,把每一个都去掉。 如果您知道只有一场比赛,您可以通过以下方式简化:

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

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

doc.xpath("//Description[ID='1234']").remove
但是,如果制作XPath不是您的乐趣所在,而编写Ruby则是如此,那么您可以更努力地使用Ruby,但效率会稍低一些:

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

查找所有名为 但是,如果文本是1234,那么就把它删减 将此映射为每个节点上调用.parent的结果 然后打电话,把每一个都去掉。 如果您知道只有一场比赛,您可以通过以下方式简化:

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

??1 xpath将返回一个节点集。如果文档中有多个节点,所有节点都将返回,文本将从所有节点返回内容,这将使id==1234不匹配。类似地,xpath//Description.remove将从文档中删除所有节点。-1 xpath将返回节点集。如果文档中有多个节点,所有节点都将返回,文本将从所有节点返回内容,这将使id==1234不匹配。类似地,xpath//Description.remove将从文档中删除所有节点。这是一个很好的解决方案。谢谢。注意:如果您的XPath看起来更神奇,那么它会变得更简单://Description[ID='1234']谢谢@Phrogz,我不知道您能做到这一点。这是一个很好的解决方案。谢谢。注意:如果您的XPath看起来更神奇,那么它会变得更简单://Description[ID='1234']谢谢@Phrogz,我不知道您能做到这一点。