使用Nokogiri创建XML节点

时间:2014-10-28 05:05:02

标签: ruby xml nokogiri

我在创建节点并将其添加到XML文件时遇到问题:

<mainnode>
    <secnode>
         <data1></data2>
         <data2></data2>
    </secnode>
</mainnode>

我希望能够像这样添加到文件中:

<mainnode>
    <secnode>
         <data1></data2>
         <data2></data2>
    </secnode>
    <secnode>
         <data1></data2>
         <data2></data2>
    </secnode>
</mainnode>

我无法获得使用Nokogiri添加节点的概念。

这是我目前的代码:

def openXML
    f = File.open("file.xml")
    doc = Nokogiri::XML(f)
end

def parseXML
    mainnode.name = 'mainnode'
    f = openXML
    temp = Nokogiri::XML::Node.new "secnode", f
    mainnode.add_next_sibling(temp)

end

我错过了哪些概念?

我需要能够将实例变量添加到<data1><data2>,但我发现Nokogiri教程在这个领域没有多大帮助,并且没有让它过去只添加{{ 1}}节点作为<secnode>的子节点。

感谢任何帮助。

2 个答案:

答案 0 :(得分:6)

在Nokogiri中添加节点要比你想象的容易得多,但你的问题并不是很清楚。

如果您想复制现有节点:

require 'nokogiri'

xml = <<EOT
<mainnode>
    <secnode>
         <data1></data2>
         <data2></data2>
    </secnode>
</mainnode>
EOT

doc = Nokogiri::XML(xml)

secnode = doc.at('secnode')
doc.root.add_child secnode.dup
puts doc.to_xml

运行时会产生以下结果:

<?xml version="1.0"?>
<mainnode>
    <secnode>
         <data1/>
         <data2/>
    </secnode>
<secnode>
         <data1/>
         <data2/>
    </secnode></mainnode>

时髦对齐是附加用于缩进的插入文本节点的结果。生成的XML有效。

如果你要添加一组不同的节点,它仍然很容易:

要求&#39; nokogiri&#39;

xml = <<EOT
<mainnode>
    <secnode>
         <data1></data2>
         <data2></data2>
    </secnode>
</mainnode>
EOT

node_to_add = <<EOT
<secnode>
  <data3 />
  <data4 />
</secnode>
EOT

doc = Nokogiri::XML(xml)

doc.root.add_child node_to_add
puts doc.to_xml

哪个输出:

<?xml version="1.0"?>
<mainnode>
    <secnode>
         <data1/>
         <data2/>
    </secnode>
<secnode>
  <data3/>
  <data4/>
</secnode>
</mainnode>

您可以将其用作模板:

require 'nokogiri'

xml = <<EOT
<mainnode>
    <secnode>
         <data1></data2>
         <data2></data2>
    </secnode>
</mainnode>
EOT

v1 = 'foo'
v2 = 'bar'
node_to_add = <<EOT
<secnode>
  <data3>#{ v1 }</data3>
  <data4>#{ v2 }</data4>
</secnode>
EOT

doc = Nokogiri::XML(xml)

doc.root.add_child node_to_add
puts doc.to_xml

看起来像:

<?xml version="1.0"?>
<mainnode>
    <secnode>
         <data1/>
         <data2/>
    </secnode>
<secnode>
  <data3>foo</data3>
  <data4>bar</data4>
</secnode>
</mainnode>

Nokogiri通过使用XML或HTML的字符串表示来创建要添加的节点非常容易,然后它可以即时转换。

答案 1 :(得分:4)

require 'nokogiri'

def parse_xml_file(file_name)
  f = File.read(file_name)
  Nokogiri::XML(f) # do not need variable here; it's the return value of the method
end

def add_element(doc, node_name)
  new_element = Nokogiri::XML::Node.new(node_name, doc)
  new_element.content = "anything"
  doc.root.add_child(new_element)
end

doc = parse_xml_file("sample.xml")
add_element(doc, 'secnode')

puts doc.to_s

你的第mainnode.name = 'mainnode'行没有做任何事情会引发错误;你还没有从XML文档中选择任何东西。

您应该阅读遍历XML DOM并选择节点。试试这个底漆: https://blog.engineyard.com/2010/getting-started-with-nokogiri

你说你读过Nokogiri文档,但我也回过头来重读这篇文章: http://www.nokogiri.org/tutorials/searching_a_xml_html_document.html

最后,通过解析IRB中的文档并了解您可以用它做什么,来玩nokogiri。这是探索和感受nokogiri的好方法。

相关问题