2009-03-08 8 views
1

Je dois ajouter un élément à un document XML existant qui utilise un espace de noms qui n'existe pas dans l'original. Comment puis-je faire cela?Ajouter un espace de noms XML à un document existant dans ruby ​​

Idéalement, je voudrais utiliser REXML pour la portabilité, mais toute bibliothèque XML courante serait acceptable. Une solution idéale serait intelligente sur les collisions d'espaces de noms.

J'ai un document XML qui ressemble à ceci:

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

et ajouter:

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

Cédant quelque chose d'équivalent à:

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

Répondre

1

Il se c'est un muet question. Si le document initial et l'élément à ajouter sont tous les deux cohérents en interne, les espaces de noms sont corrects. Donc, ce qui est équivalent au document final:

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

Il est important que le document initial et l'élément définissent un espace de noms par défaut avec l'attribut xmlns.

Supposons que le document initial est dans initial.xml et que l'élément est dans element.xml. Pour créer ce document final avec REXML, il suffit de:

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