使用Nokogiri插入和删除XML节点和元素

我想提取XML文件的一部分,并记下我在该文件中提取了一些部分,比如“这里提取的东西”。

我正试图用Nokogiri这样做,但似乎没有真正记录如何:

  1. 删除
  2. 更改该完整元素的inner_text

有什么线索吗?

Nokogiri让这很容易。 以此文档为例,以下代码将找到所有vitamins标签,移除他们的孩子(以及孩子的孩子等),并将其内部文本更改为“删除子项”。:

 require 'nokogiri' io = File.open('sample.xml', 'r') doc = Nokogiri::XML(io) io.close doc.search('//vitamins').each do |node| node.children.remove node.content = 'Children removed.' end 

给定的food节点将如下所示:

  Avocado Dip Sunnydale 29  11 3 5 210 2 0 1  0 0   0 0   

对此:

  Avocado Dip Sunnydale 29  11 3 5 210 2 0 1 Children removed.  0 0   

以前的Nokogiri例子让我朝着正确的方向前进,但是使用doc.search留下了一个畸形的//vitamins ,所以我使用了CSS:

 require "rubygems" require "nokogiri" f = File.open("food.xml") doc = Nokogiri::XML(f) doc.css("food vitamins").each do |node| puts "\r\n[debug] Before: vitamins= \r\n#{node}" node.children.remove node.content = "Children removed" puts "\r\n[debug] After: vitamins=\r\n#{node}" end f.close 

结果如下:

 debug] Before: vitamins=  0 0  [debug] After: vitamins= Children removed 

你可以这样做:

 doc=Nokogiri::XML(your_document) note=doc.search("note") # find all tags with the node_name "note" note.remove 

虽然这会删除标记内的所有子节点,但我不确定如何“更改所有音符元素的inner_text”。 我认为inner_text不适用于Nokogiri :: XML :: Element。

这是我要做的:

首先解析一些XML:

 require 'nokogiri' doc = Nokogiri::XML(<    65 20 300 2400 300 25 50   Avocado Dip Sunnydale 29  11 3 5 210 2 0 1  0 0   0 0    EOT 

如果我想删除节点的内容,我可以删除其children节点或为其内容指定nil:

 doc.at('total-fat').to_xml # => "65" doc.at('total-fat').children.remove doc.at('total-fat').to_xml # => "" 

要么:

 doc.at('saturated-fat').to_xml # => "20" doc.at('saturated-fat').content = nil doc.at('saturated-fat').to_xml # => "" 

如果我想从节点中提取文本以便以其他方式使用:

 food = doc.at('food').text # => "\n Avocado Dip\n Sunnydale\n 29\n \n 11\n 3\n 5\n 210\n 2\n 0\n 1\n \n 0\n 0\n \n \n 0\n 0\n \n " 

要么:

 food = doc.at('food').children.map(&:text) # => ["\n ", # "Avocado Dip", # "\n ", # "Sunnydale", # "\n ", # "29", # "\n ", # "", # "\n ", # "11", # "\n ", # "3", # "\n ", # "5", # "\n ", # "210", # "\n ", # "2", # "\n ", # "0", # "\n ", # "1", # "\n ", # "\n 0\n 0\n ", # "\n ", # "\n 0\n 0\n ", # "\n "] 

或者你想要破坏文本。

并且,如果您想标记您已删除文本:

 doc.at('food').content = 'REMOVED' doc.at('food').to_xml # => "REMOVED" 

您也可以使用XML注释:

 doc.at('food').children = '' doc.at('food').to_xml # => "\n \n"