2010-11-05 18 views
5

Mi piacerebbe fare questomodificare lo spazio dei nomi di un elemento con XSLT

<hello> 
    <one> 
    <paragraph>p1</paragraph> 
    </one> 
</hello> 

in questo

<x:hello y:an_attribute="a value for an_attribute" xmlns:x="some_new_namespace" xmlns:y="other_ns"> 
    <one> 
    <paragraph>p1</paragraph> 
    </one> 
</x:hello> 

questo è il foglio di stile mi si avvicinò con:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:param name="element_localname" select="'hello'"/> 


    <xsl:template match="node()"> 
     <xsl:choose> 
      <xsl:when test="local-name() = $element_localname"> 
       <xsl:element name="{$element_localname}" namespace="some_new_namespace"> 
        <xsl:attribute name="an_attribute" namespace="other_ns">a value for an_attribute</xsl:attribute> 
        <xsl:apply-templates select="node()"/> 
       </xsl:element> 
      </xsl:when> 

      <!-- copy the rest as is --> 
      <xsl:otherwise> 
       <xsl:copy> 
        <xsl:apply-templates select="node()" /> 
       </xsl:copy> 
      </xsl:otherwise> 

     </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 

ma per qualche strana ragione, l'attributo che sto aggiungendo all'elemento ha lo stesso spazio dei nomi dell'elemento radice stesso? perché?

<ns0:hello xmlns:ns0="other_ns" ns0:an_attribute="a value for an_attribute"> 
    <one> 
    <paragraph>p1</paragraph> 
    </one> 
</ns0:hello> 

Grazie per la lettura.

+0

onda la fonte attraverso la vostra trasformazione in xsltproc mi dà ' 'per l'elemento' hello', che sembra essere quello che vuoi. Mi chiedo se si tratta di una cosa XSL 1.0 contro XSL 2.0? –

+0

Grazie per aver provato. Sto usando la build wtp di eclipse nel processore xslt. Non ho idea di quale implementazione usi. – Luca

+0

Buona domanda, +1. Vedi la mia risposta per una soluzione molto più semplice e più breve di quella attualmente accettata. :) –

risposta

0

Questo foglio di stile:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:x="some_new_namespace" 
    xmlns:y="other_ns"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:param name="element_localname" select="'hello'"/> 
    <xsl:template match="node()|@*" name="identity"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="*"> 
     <xsl:choose> 
      <xsl:when test="local-name() = $element_localname"> 
       <xsl:element name="x:{$element_localname}"> 
        <xsl:attribute name="y:an_attribute"> 
         <xsl:text>a value for an_attribute</xsl:text> 
        </xsl:attribute> 
        <xsl:apply-templates select="node()|@*"/> 
       </xsl:element> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:call-template name="identity" /> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

uscita:

<x:hello y:an_attribute="a value for an_attribute" 
     xmlns:y="other_ns" xmlns:x="some_new_namespace"> 
    <one> 
     <paragraph>p1</paragraph> 
    </one> 
</x:hello> 
+0

Grazie, questo funziona. Hai risolto il mio problema :) Hai un'idea del perché il mio esempio no? – Luca

+0

@Luca: sei il benvenuto. Questo è il tuo output del codice: ' p1' So , si dispone di un elemento root dello spazio dei nomi defalut con un attributo in uno spazio dei nomi non null (il prefisso viene aggiunto automaticamente da Namespaces Fixup) e una dichiarazione dello spazio dei nomi di default 'xmlns =" ​​"' (In XML 1.1 anche la dichiarazione degli spazi dei nomi con prefisso può essere reimpostata). . In conclusione: se vuoi un legame URI con prefisso-spazio dei nomi specifico, dichiaralo nel foglio di stile. –

4

Questo è molto più semplice di quanto possa sembrare:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:x="some_new_namespace" xmlns:y="other_ns" 
exclude-result-prefixes="x y"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="/*"> 
    <x:hello y:an_attribute="a value for an_attribute"> 
    <xsl:apply-templates/> 
    </x:hello> 
</xsl:template> 
</xsl:stylesheet> 

quando questa trasformazione viene applicata al previsto Documento XML:

<hello> 
    <one> 
     <paragraph>p1</paragraph> 
    </one> 
</hello> 

The Wanted, risultato corretto è prodotto:

<x:hello xmlns:x="some_new_namespace" xmlns:y="other_ns" y:an_attribute="a value for an_attribute"> 
    <one> 
     <paragraph>p1</paragraph> 
    </one> 
</x:hello> 
Problemi correlati