2014-10-28 85 views
3

XML節點我有創建節點並將它們添加到一個XML文件中的問題:創建使用引入nokogiri

<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教程不會在這方面有很大幫助,並沒有使其過去只需添加<secnode>節點的<mainnode>一個孩子。

任何幫助表示讚賞。

+0

你從上面的代碼中得到什麼錯誤? – 2014-10-28 05:06:18

+0

另外:什麼是'inst'? – 2014-10-28 05:06:47

+0

我得到一個錯誤inst是未定義的。但我的問題在於我不知道如何初始化inst作爲父節點來追加子節點。 – 2014-10-28 05:13:01

回答

5

在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是有效的。

如果要添加一組不同的節點,它仍然很容易:

需要 '引入nokogiri'

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的字符串表示,它然後在飛行轉換添加節點。

+0

是的,比我的12線實施方式更好。感謝您的見解! – 2014-10-28 21:41:04

+0

在Nokogiri文檔中,您會看到'node_or_tags'作爲各種方法的參數。這就是他們如何使用字符串或文本表示來描述的方式。 – 2014-10-28 21:53:51

+0

所以它是或者。我可以將節點附加到節點,或將字符串(標記)附加到節點。 – 2014-10-28 22:15:52

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的好方法。

+0

起初我遇到了問題。你的代碼之後唯一的補充頁面是。我的問題是我沒有添加任何內容到節點。內容添加到new_element.content後,它工作。好的建議,我花了幾個小時在irb和更多的文檔。謝謝。 – 2014-10-28 16:03:34