我想提取XML文件的部分并记录我在该文件中提取的某些部分,比如“东西在这里提取”。
我试图用引入nokogiri要做到这一点,但它似乎没有真正了解如何进行记录:
- 删除所有孩子的
<Nokogiri::XML::Element>
- 改变
inner_text
是完整的元素的
任何线索?
我想提取XML文件的部分并记录我在该文件中提取的某些部分,比如“东西在这里提取”。
我试图用引入nokogiri要做到这一点,但它似乎没有真正了解如何进行记录:
<Nokogiri::XML::Element>
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
节点会从这样看:
<food>
<name>Avocado Dip</name>
<mfr>Sunnydale</mfr>
<serving units="g">29</serving>
<calories total="110" fat="100"/>
<total-fat>11</total-fat>
<saturated-fat>3</saturated-fat>
<cholesterol>5</cholesterol>
<sodium>210</sodium>
<carb>2</carb>
<fiber>0</fiber>
<protein>1</protein>
<vitamins>
<a>0</a>
<c>0</c>
</vitamins>
<minerals>
<ca>0</ca>
<fe>0</fe>
</minerals>
</food>
为此:
<food>
<name>Avocado Dip</name>
<mfr>Sunnydale</mfr>
<serving units="g">29</serving>
<calories total="110" fat="100"/>
<total-fat>11</total-fat>
<saturated-fat>3</saturated-fat>
<cholesterol>5</cholesterol>
<sodium>210</sodium>
<carb>2</carb>
<fiber>0</fiber>
<protein>1</protein>
<vitamins>Children removed.</vitamins>
<minerals>
<ca>0</ca>
<fe>0</fe>
</minerals>
</food>
前面的例子引入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=
<vitamins>
<a>0</a>
<c>0</c>
</vitamins>
[debug] After: vitamins=
<vitamins>Children removed</vitamins>
你可以像下面这样做:
doc=Nokogiri::XML(your_document)
note=doc.search("note") # find all tags with the node_name "note"
note.remove
虽然这将在中删除所有的儿童<note>
标签,我不知道如何“改变inner_text”的所有笔记的。 我觉得inner_text
不适用于一个引入nokogiri :: XML ::元素。
这是我会怎么做:
第一解析一些XML:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="nutrition.css"?>
<nutrition>
<daily-values>
<total-fat units="g">65</total-fat>
<saturated-fat units="g">20</saturated-fat>
<cholesterol units="mg">300</cholesterol>
<sodium units="mg">2400</sodium>
<carb units="g">300</carb>
<fiber units="g">25</fiber>
<protein units="g">50</protein>
</daily-values>
<food>
<name>Avocado Dip</name>
<mfr>Sunnydale</mfr>
<serving units="g">29</serving>
<calories total="110" fat="100"/>
<total-fat>11</total-fat>
<saturated-fat>3</saturated-fat>
<cholesterol>5</cholesterol>
<sodium>210</sodium>
<carb>2</carb>
<fiber>0</fiber>
<protein>1</protein>
<vitamins>
<a>0</a>
<c>0</c>
</vitamins>
<minerals>
<ca>0</ca>
<fe>0</fe>
</minerals>
</food>
</nutrition>
EOT
如果我想删除一个节点的内容,我可以删除其children
或指定零到它的内容:
doc.at('total-fat').to_xml # => "<total-fat units=\"g\">65</total-fat>"
doc.at('total-fat').children.remove
doc.at('total-fat').to_xml # => "<total-fat units=\"g\"/>"
要么:
doc.at('saturated-fat').to_xml # => "<saturated-fat units=\"g\">20</saturated-fat>"
doc.at('saturated-fat').content = nil
doc.at('saturated-fat').to_xml # => "<saturated-fat units=\"g\"/>"
如果我想提取使用其他方式的节点文字:
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 # => "<food>REMOVED</food>"
你也可以使用使用XML注释:
doc.at('food').children = '<!-- REMOVED -->'
doc.at('food').to_xml # => "<food>\n <!-- REMOVED -->\n</food>"