2010-05-10 16 views
13

espero que puedan ayudar ... Asumamos que he XML siguiente:añadir espacio de nombres + prefijo a XML utilizando XSL

<data> 
    <token> 
     <sessionId>12345</sessionId>   
     <userId>john</userId> 
     <moreInfo> 
     <bla> ..... 
     </bla> 
     </moreInfo> 
    </token> 
</data> 

Y necesito que esto se convierta

<login:data xmlns:login="http://my.ns.uri"> 
     <login:token> 
      <login:sessionId>12345</sessionId>   
      <login:userId>john</userId> 
      <login:moreInfo> 
      <login:bla> ..... 
      </login:bla> 
      </login:moreInfo> 
     </login:token> 
    </login:data> 

¿Puedo hacer esto con XSL? Lo intenté pero fallé miserablemente ... ¡Cualquier ayuda sería muy apreciada!

Gracias, Jan

+2

En realidad, lo que se produce es mala XML. Desea 'xmlns: login =" http: //my.ns.uri "'. –

+0

tienes razón, eso es lo que quiero. xmlns: login = "http: //my.ns.uri" pero ¿cuál sería el XSL para hacer algo como eso? – Jan

+0

Buena pregunta (+1). Vea mi respuesta para una solución completa y correcta. :) –

Respuesta

12

Uso:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:login="http://my.ns.uri"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*"> 
    <xsl:element name="login:{name()}" namespace="http://my.ns.uri"> 
    <xsl:copy-of select="namespace::*"/> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:element> 
</xsl:template> 
</xsl:stylesheet> 

Cuando se aplica esta transformación en el documento XML proporcionado, el resultado deseado, correcta se produce:

<login:data xmlns:login="http://my.ns.uri"> 
    <login:token> 
     <login:sessionId>12345</login:sessionId> 
     <login:userId>john</login:userId> 
     <login:moreInfo> 
     <login:bla> ..... 
     </login:bla> 
     </login:moreInfo> 
    </login:token> 
</login:data> 
+0

Muchas gracias, eso es exactamente lo que quise decir y necesitaba, me salvaste de un fuerte dolor de cabeza :) – Jan

0
<xsl:template match="*"> 
    <xsl:element name="{local-name()}" namespace="http://my.ns.uri"> 
    <xsl:apply-templates /> 
    </xsl:element> 
</xsl:template> 
+0

De acuerdo, entiendo esto. Pero, ¿cómo puedo cambiar los prefijos de todos los elementos? – Jan

+0

Los prefijos son algo bastante fluido en XML. Quiero decir, que la especificación dice explícitamente que son * arbitrarios *. Por lo tanto, su procesador XSLT sería libre de cambiarlos a lo que quiera. Sin embargo, todos los motores XSLT (conocidos por mí) vuelven a utilizar los prefijos que escribió en la etiqueta de apertura '', si no hay motivos para no hacerlo (como 'exclude-result-prefix' de XSLT) – Boldewyn

+0

Ok, déjame jugar con esto ... ¡Gracias! – Jan

0

XSLT 2.0 es más eficiente y compacto. Admite agregar espacios de nombres al nodo directamente. No necesitamos definir nada en el inicio de la hoja de estilo también.

Aquí está la especificación: creating namespace prefix

Uso:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:template match="*"> 
    <xsl:element name="login:{name()}" xmlns:login="http://my.ns.uri"> 
    <xsl:namespace name="login">http://my.ns.uri</xsl:namespace> 
    <xsl:value-of select="node()"/> 
    <xsl:apply-templates select="*"/> 
    </xsl:element> 
</xsl:template> 
</xsl:stylesheet> 

Se dará la salida:

<login:data xmlns:login="http://my.ns.uri"> 
    <login:token> 
     <login:sessionId>12345</login:sessionId> 
     <login:userId>john</login:userId> 
     <login:moreInfo> 
     <login:bla> ..... 
     </login:bla> 
     </login:moreInfo> 
    </login:token> 
</login:data> 
Cuestiones relacionadas