我正在尝试在以下XML中添加一个<EventRouter>
元素:
<EventRouters>
<EventRouter id="Important Events to Log File" class="com.cyclonecommerce.events2.router.LogFileRouter" active="true">
<Parameters file="../logs/%nodeName%_events.log"
rollOnStart="false" autoFlush="true"
maxFileSize="2M" maxBackupFiles="5"/>
<MetadataProcessorListRef ref="Messaging"/>
<EventFilterRef ref="Important"/>
</EventRouter>
<EventRouter id="Message Detail to Log File" class="com.cyclonecommerce.events2.router.LogFileRouter" active="false">
<Parameters file="../logs/%nodeName%_message_detail.log"
rollOnStart="true" autoFlush="true"
maxFileSize="2M" maxBackupFiles="5"/>
<MetadataProcessorListRef ref="Messaging"/>
<EventFilterRef ref="Message Detail"/>
</EventRouter>
</EventRouters>
我能够将节点附加到节点集但是在保存XML之后我没有得到我想要的更新的XML:
require 'nokogiri'
if File.exist?('a.xml')
data = File.read("a.xml")
end
doc = Nokogiri::XML.parse data
doc2=doc.xpath("//EventRouters/EventRouter")
event_router = Nokogiri::XML::Node.new("EventRouter",doc)
event_router['id'] = "some"
param_node = Nokogiri::XML::Node.new("Parameters",doc)
param_node.content = "some content"
event_router << param_node
doc2<< event_router
File.open('test.xml', 'w') do |file|
file.print doc.to_xml
end
答案 0 :(得分:1)
更改
doc2=doc.xpath("//EventRouters/EventRouter")
要
doc2 = doc.at_xpath("//EventRouters")
xpath
返回一个数组。您可以使用at_xpath
来获取第一个元素。还要摆脱/EventRouter
,因为我想你想把另一个'EventRouter'项添加到EventRouters
答案 1 :(得分:0)
添加新节点很简单。基本思想类似于解析XML或HTML:
Nokogiri使用字符串添加节点变得容易,它将解析并转换为节点:
require 'nokogiri'
doc = Nokogiri::XML('<xml><node/></xml>')
node = doc.at('node')
node.add_child('<foo>bar</foo>')
doc.to_xml # => "<?xml version=\"1.0\"?>\n<xml>\n <node>\n <foo>bar</foo>\n </node>\n</xml>\n"
您可以使用更长的创建新节点的路线,但我发现更容易构建字符串。
使用您的代码作为依据,以下是我的编写方式:
require 'nokogiri'
data = DATA.read
doc = Nokogiri::XML.parse data
doc.xpath("//EventRouters/EventRouter").each do |event_router|
event_router.add_next_sibling("<EventRouter id='some'><Parameters>some content</Parameters></EventRouter>")
end
puts doc.to_xml
__END__
<EventRouters>
<EventRouter>original1</EventRouter>
<EventRouter>original2</EventRouter>
</EventRouters>
运行结果:
<?xml version="1.0"?>
<EventRouters>
<EventRouter>original1</EventRouter><EventRouter id="some"><Parameters>some content</Parameters></EventRouter>
<EventRouter>original2</EventRouter><EventRouter id="some"><Parameters>some content</Parameters></EventRouter>
</EventRouters>
您尝试使用<<
附加到NodeSet,而NodeSet不会按照您的想法执行操作:
doc = Nokogiri::XML.parse data
ers = doc.search('EventRouter')
ers << Nokogiri::XML::Node.new('<foo/>', doc)
附加到ers
,这是一个NodeSet,不会将新节点应用于集合中的所有元素:
doc.to_xml # => "<?xml version=\"1.0\"?>\n<EventRouters>\n <EventRouter>original1</EventRouter>\n <EventRouter>original2</EventRouter>\n</EventRouters>\n"
相反,它将它附加到集合的末尾:
ers.to_xml # => "<EventRouter>original1</EventRouter><EventRouter>original2</EventRouter><<foo/>/>"