我正在实现一个需要名称空间的XML数据导出器。我正在使用Nokogiri的XML Builder (版本1.4.0)来做这件事,但是,我不能让Nokogiri创建一个带有名称空间的根节点。
这是可行的:
Nokogiri::XML::Builder.new { |xml| xml.root('xmlns:foobar' => 'my-ns-url') }.to_xml
<?xml version="1.0"?>
<root xmlns:foobar="my-ns-url"/>
如下所示:
Nokogiri::XML::Builder.new do |xml|
xml.root('xmlns:foobar' => 'my-ns-url') { xml['foobar'].child }
end.to_xml
<?xml version="1.0"?>
<root xmlns:foobar="my-ns-url">
<foobar:child/>
</root>
但是,我需要像<foo:root>
这样的东西,但这不起作用:
Nokogiri::XML::Builder.new { |xml| xml['foobar'].root('xmlns:foobar' => 'my-ns-url') }.to_xml
NoMethodError: undefined method `namespace_definitions' for #<Nokogiri::XML::Document:0x11bfef8 name="document">
显然,命名空间必须在使用前定义,因此无法将其添加到根节点。
我在Nokogiri的邮件列表中找到了"Define root node with a namespace?“,但没有回复。
有谁有解决方案吗?
发布于 2009-12-06 19:14:05
require 'rubygems'
require 'nokogiri'
puts Nokogiri::XML::Builder.new do |xml|
xml.root("xmlns:foo"=>"url") do
xml.parent.namespace = xml.parent.namespace_definitions.find{|ns|ns.prefix=="foo"}
xml['foo'].child
end
end.to_xml
您不能在定义名称空间之前使用xml['foo']
,即在将其作为参数传递给根节点之前,因此,上面的代码将事后的名称空间添加到根节点。
发布于 2012-03-28 01:02:45
两年后,我找到了一种更简洁的方法,使用Nokogiri::XML::Builder
的文档引用来检索根节点并将名称空间添加到根节点中,与前面的解决方案一样,它需要根节点存在,然后才能向其添加名称空间。
我将<root>
元素改为<rootElement>
,这样就更清楚了:
builder = Nokogiri::XML::Builder.new do |xml|
xml.rootElement do
# create a namespace and save it for later
ns = xml.doc.root.add_namespace_definition('foo', 'my-ns-url')
# you can also create multiple name spaces
xml.doc.root.add_namespace_definition('bar', 'http://example.com/bar')
# assign the saved namespace to rootElement
xml.doc.root.namespace = ns
xml['foo'].child
xml['bar'].child
end
end
现在,builder.to_xml
将返回:
<?xml version="1.0"?>
<foo:rootElement xmlns:foo="my-ns-url" xmlns:bar="http://example.com/bar">
<foo:child/>
<bar:child/>
</foo:rootElement>
我更喜欢这种方式,因为您不必搜索名称空间,而且添加多个名称空间也更容易。
发布于 2015-12-01 17:02:41
在Luke的回答三年后,它变得更加简单。您现在可以“在”定义名称空间之前使用它。这段代码:
require 'nokogiri'
NAMESPACES = { 'xmlns:foo' => 'bar', 'xmlns:baz' => 'bat' }
builder = Nokogiri::XML::Builder.new { |xml|
xml['foo'].RootElement(NAMESPACES) {
xml['baz'].FirstChild
}
}
puts builder.to_xml
输出此XML:
<?xml version="1.0"?>
<foo:RootElement xmlns:foo="bar" xmlns:baz="bat">
<baz:FirstChild/>
</foo:RootElement>
https://stackoverflow.com/questions/1829425
复制相似问题