Question

J'ai une XML qui déclare un espace de noms qui est utilisé uniquement pour les attributs, comme ceci:

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

Je veux utiliser XSL pour créer une copie des noeuds sélectionnés et leurs valeurs - se débarrasser des attributs. Donc, ma sortie désirée est:

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

J'ai quelques XSL qui semblent ne presque, mais je ne peux pas l'arrêter de mettre la déclaration d'espace de noms dans l'élément de haut niveau de la sortie. Mon XSL est:

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

Le premier élément de la sortie est <b xmlns:x="http://tempuri.com"> au lieu de <b>. J'ai essayé de déclarer l'espace de noms dans le XSL et de mettre le préfixe dans la liste exclude-result-prefixes, mais cela ne semble pas avoir d'effet. Qu'est-ce que je fais mal?

Mise à jour: Je l'ai trouvé que, en déclarant l'espace de noms dans le XSL et en utilisant l'attribut fonctionne extension-element-prefixes, mais cela ne semble pas juste! Je suppose que je pourrais l'utiliser, mais je voudrais savoir pourquoi le ne fonctionne pas <=>!

Mise à jour: En fait, il semble que cette solution fonctionne uniquement avec <=> moteur XSLT intégré dans XMLSpy, pas avec MSXML

.
Était-ce utile?

La solution

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

J'ai trouvé une explication .

  

Michael Kay a écrit:
  exclude-result-prefixes affecte uniquement les espaces de noms copiés à partir de la   stylesheet par un élément de résultat littéral, il ne modifie pas la copie de   namespaces de documents sources.

Autres conseils

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

Essayez ceci (notez l'attribut copy-namespaces='no'):

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

Cela supprimera l'espace de noms x de la sortie.

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

Rappelez-vous de faire deux choses lorsque vous traitez avec un espace de noms par défaut. Tout d'abord la carte en quelque chose dans la balise stylesheet, puis retirez à l'aide d'un espace de nom-alias.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top