Domanda

Ho un po 'di XML che dichiara uno spazio dei nomi che viene utilizzato solo per gli attributi, in questo modo:

<?xml version="1.0" encoding="UTF-8"?>
<a xmlns:x="http://tempuri.com">
    <b>
        <c x:att="true"/>
        <d>hello</d>
    </b>
</a>

Vorrei utilizzare XSL per creare una copia di nodi selezionati ed i loro valori - sbarazzarsi degli attributi. Quindi il mio output desiderato è:

<?xml version="1.0" encoding="UTF-8"?>
<b>
    <c />
    <d>hello</d>
</b>

ho delle XSL che fa quasi questo, ma io non riesco a fermarlo mettere la dichiarazione dello spazio dei nomi nell'elemento alto livello dell'uscita. Il mio XSL è:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/">
        <xsl:apply-templates select="/a/b"/>
    </xsl:template>

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

Il primo elemento della produzione è <b xmlns:x="http://tempuri.com"> anziché <b>. Ho provato dichiarare lo spazio dei nomi nella XSL e mettendo il prefisso nel exclude-result-prefixes lista, ma questo non sembra avere alcun effetto. Che cosa sto facendo di sbagliato?

UPDATE: ho trovato che dichiarando lo spazio dei nomi nella XSL e utilizzando il extension-element-prefixes attributo funziona, ma questo non mi sembra giusto! Credo che avrei potuto utilizzare questo, ma mi piacerebbe sapere perché il <=> non funziona!

UPDATE: In realtà, sembra che questa soluzione <=> funziona solo con XMLSpy di motore incorporato XSLT, non con MSXML

.
È stato utile?

Soluzione

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:x="http://tempuri.com">
    <xsl:template match="/">
        <xsl:apply-templates select="/a/b"/>
    </xsl:template>

    <xsl:template match="*">
        <xsl:element name="{local-name(.)}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="@*">
        <xsl:copy/>
    </xsl:template>

    <!-- This empty template is not needed.
Neither is the xmlns declaration above:
    <xsl:template match="@x:*"/> -->
</xsl:stylesheet>

Ho trovato una spiegazione qui .

  

Michael Kay ha scritto:
  escludere-risultato-prefissi colpisce solo gli spazi dei nomi copiati dalla   foglio di stile da un elemento risultato letterale, non influenza la copia di   spazi dei nomi da documenti di origine.

Altri suggerimenti

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:x="http://tempuri.com"
  exclude-result-prefixes="x"
>

  <!-- the identity template copies everything 1:1 -->
  <xsl:template match="@* | node()">
     <xsl:copy>
      <xsl:apply-templates select="@* | node()" />
    </xsl:copy>
  </xsl:template>

  <!-- this template explicitly cares for namespace'd attributes -->
  <xsl:template match="@x:*">
    <xsl:attribute name="{local-name()}">
      <xsl:value-of select="." />
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

Prova questo (notare l'attributo copy-namespaces='no'):

<xsl:template match="node()">
    <xsl:copy copy-namespaces="no">
            <xsl:apply-templates select="node()"/>
    </xsl:copy>
</xsl:template>

Questo rimuoverà la x namespace dall'uscita.

<xsl:namespace-alias result-prefix="#default" stylesheet-prefix="x" />

Ricordate di fare due cose quando avete a che fare con uno spazio dei nomi predefinito. Prima mappa in qualcosa nel tag foglio di stile, e quindi rimuoverlo con uno spazio dei nomi-alias.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top