2012-02-16 38 views
2

我有一個XML文件是這樣的:引入nokogiri:新子控制元素前綴elments

<?xml version="1.0" encoding="UTF-8"?> 
<foo:root xmlns:foo="http://abc.com#" xmlns:bar="http://def.com" xmlns:ex="http://ex.com"> 
    <foo:element foo:attribute="attribute_value"> 
    <bar:otherElement foo:otherAttribute="otherAttributeValue"/> 
    </foo:element> 
</foo:root> 

我需要的子元素添加到元素,使它看起來像這樣:

<?xml version="1.0" encoding="UTF-8"?> 
<foo:root xmlns:foo="http://abc.com#" xmlns:bar="http://def.com" xmlns:ex="http://ex.com"> 
    <foo:element foo:attribute="attribute_value"> 
    <bar:otherElement foo:otherAttribute="otherAttributeValue"/> 
    <bar:otherElement foo:otherAttribute="newAttributeValue"/> 
    <ex:yetAnotherElement foo:otherAttribute="yetANewAttributeValue"/> 
    </foo:element> 
</foo:root> 

我可以使用以下方法在正確的位置添加元素:

require 'rubygems' 
require 'nokogiri' 
doc = Nokogiri::XML::Document.parse(File.open("myfile.xml")) 
el = doc.at_xpath('//foo:element') 

newEl = Nokogiri::XML::Node.new("otherElement", doc)    
newEl["foo:otherAttribute"] = "newAttributeValue" 
el.add_child(newEl) 

newEl = Nokogiri::XML::Node.new("yetAnotherElement", doc)   
newEl["foo:otherAttribute"] = "yetANewAttributeValue" 
el.add_child(newEl) 

但是,新元素的前綴總是「foo」:

<foo:root xmlns:foo="http://abc.com#" xmlns:bar="http://def.com" xmlns:ex="http://ex.com"> 
    <foo:element foo:attribute="attribute_value"> 
    <bar:otherElement foo:otherAttribute="otherAttributeValue" /> 
    <foo:otherElement foo:otherAttribute="newAttributeValue" /> 
    <foo:yetAnotherElement foo:otherAttribute="yetANewAttributeValue" /> 
    </foo:element> 
</foo:root> 

如何在這些新的子元素的元素名稱上設置前綴?謝謝, 銳衡

回答

3

只需添加幾行代碼,你會得到想要的結果(有關定義命名空間,正交質疑,並固定在編輯刪除位):

require 'rubygems' 
require 'nokogiri' 
doc = Nokogiri::XML::Document.parse(File.open("myfile.xml")) 
el = doc.at_xpath('//foo:element') 

newEl = Nokogiri::XML::Node.new("otherElement", doc)    
newEl["foo:otherAttribute"] = "newAttributeValue" 
# ADDITIONAL CODE 
newEl.namespace = doc.root.namespace_definitions.find{|ns| ns.prefix=="bar"} 
# 
el.add_child(newEl) 

newEl = Nokogiri::XML::Node.new("yetAnotherElement", doc)   
newEl["foo:otherAttribute"] = "yetANewAttributeValue" 
# ADDITIONAL CODE 
newEl.namespace = doc.root.namespace_definitions.find{|ns| ns.prefix == "ex"} 
# 
el.add_child(newEl) 

和結果:

<?xml version="1.0" encoding="UTF-8"?> 
<foo:root xmlns:abc="http://abc.com#" xmlns:def="http://def.com" xmlns:ex="http://ex.com" xmlns:foo="http://foo.com" xmlns:bar="http://bar.com"> 
    <foo:element foo:attribute="attribute_value"> 
    <bar:otherElement foo:otherAttribute="otherAttributeValue"/> 
    <bar:otherElement foo:otherAttribute="newAttributeValue"/> 
    <ex:yetAnotherElement foo:otherAttribute="yetANewAttributeValue"/> 
    </foo:element> 
</foo:root> 
+1

感謝。這工作完美。我已更正原始帖子中的示例以包含正確的名稱空間定義。歡呼 – 2012-02-16 09:26:03

1

未定義名稱空間'foo'。

有關詳細信息,請參閱本: Nokogiri/Xpath namespace query

+2

我在原來的文章中更正了這個。謝謝! – 2012-02-16 09:27:04