2009-03-08 10 views
1

Ich muss ein Element zu einem vorhandenen XML-Dokument hinzufügen, das einen Namespace verwendet, der nicht im Original vorhanden ist. Wie mache ich das?Hinzufügen von XML-Namespace zu vorhandenem Dokument in Ruby

Idealerweise würde ich gerne REXML für die Portabilität verwenden, aber jede gängige XML-Bibliothek wäre in Ordnung. Eine ideale Lösung wäre, wenn es um Namespace-Kollisionen geht.

Ich habe ein XML-Dokument, das wie folgt aussieht:

<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> 

und fügen:

<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> 

etwas nachgebend entspricht:

<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> 

Antwort

1

Es stellt sich heraus, das ist ein dummer Frage. Wenn sowohl das ursprüngliche Dokument als auch das hinzuzufügende Element intern konsistent sind, sind die Namespaces in Ordnung. Das ist also gleichbedeutend mit dem Abschlussdokument:

<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> 

Es ist wichtig, dass sowohl das Ausgangsdokument und das Element einen Standard-Namespace mit dem xmlns Attribute definieren.

Angenommen, das ursprüngliche Dokument befindet sich in initial.xml, und das Element befindet sich in element.xml. Um dieses endgültige Dokument mit REXML zu erstellen, einfach:

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