将XML命名空间添加到ruby中的现有文档

时间:2009-03-08 08:04:29

标签: xml ruby namespaces rexml

我需要在现有XML文档中添加一个元素,该文档使用原始文件中不存在的命名空间。我该怎么做?

理想情况下,我想使用REXML实现可移植性,但任何常见的XML库都可以。关于名称空间冲突的理想解决方案是明智的。

我有一个xml文档,如下所示:

<xrds:XRDS
 xmlns:xrds="xri://$xrds"
 xmlns="xri://$xrd*($v*2.0)">
    <XRD>
        <Service>
            <Type>http://specs.openid.net/auth/2.0/signon</Type>
            <URI>http://provider.openid.example/server/2.0</URI>
        </Service>
    </XRD>
</xrds:XRDS>

并添加:

<Service
 xmlns="xri://$xrd*($v*2.0)"
 xmlns:openid="http://openid.net/xmlns/1.0">
    <Type>http://openid.net/signon/1.0</Type>
    <URI>http://provider.openid.example/server/1.0</URI>
    <openid:Delegate>http://example.openid.example</openid:Delegate>
</Service>

产生等同于:

的东西
<xrds:XRDS
 xmlns:xrds="xri://$xrds"
 xmlns="xri://$xrd*($v*2.0)"
 xmlns:openid="http://openid.net/xmlns/1.0">
    <XRD>
        <Service>
            <Type>http://specs.openid.net/auth/2.0/signon</Type>
            <URI>http://provider.openid.example/server/2.0</URI>
        </Service>
        <Service>
            <Type>http://openid.net/signon/1.0</Type>
            <URI>http://provider.openid.example/server/1.0</URI>
            <openid:Delegate>http://example.openid.example</openid:Delegate>
        </Service>
    </XRD>
</xrds:XRDS>

1 个答案:

答案 0 :(得分:1)

事实证明这是一个愚蠢的问题。如果初始文档和要添加的元素都是内部一致的,那么命名空间就可以了。所以这相当于最终文件:

<xrds:XRDS
 xmlns:xrds="xri://$xrds"
 xmlns="xri://$xrd*($v*2.0)">
    <XRD>
        <Service>
            <Type>http://specs.openid.net/auth/2.0/signon</Type>
            <URI>http://provider.openid.example/server/2.0</URI>
        </Service>
        <Service
         xmlns:openid="http://openid.net/xmlns/1.0" 
         xmlns="xri://$xrd*($v*2.0)">
            <Type>http://openid.net/signon/1.0</Type>
            <URI>http://provider.openid.example/server/1.0</URI>
            <openid:Delegate>http://example.openid.example</openid:Delegate>
        </Service>
    </XRD>
</xrds:XRDS>

初始文档和元素都必须使用xmlns属性定义默认命名空间。

假设初始文档位于initial.xml,元素位于element.xml。要使用REXML创建此最终文档,只需:

require 'rexml/document'
include REXML

document = Document.new(File.new('initial.xml'))
unless document.root.attributes['xmlns']
  raise "No default namespace in initial document" 
end
element = Document.new(File.new('element.xml'))
unless element.root.attributes['xmlns']
  raise "No default namespace in element" 
end

xrd = document.root.elements['XRD']
xrd.elements << element
document