2011-10-06 3 views
2

J'ai un fichier xsl qui copie un fichier xml et renomme la balise racine.xsl: Transformer les balises avec espaces de noms

<?xml version="1.0" encoding="UTF-8"?> 

<xsl:stylesheet version = '1.0' 
    xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:abc="http://example.com"> 

    <xsl:output method="xml" omit-xml-declaration="yes"/> 

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

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

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

</xsl:stylesheet> 

Cela fonctionne très bien, mais quand je décommenter le dernier bloc de traiter quelques balises namespaced je suis une erreur que le dit que quelque chose ne va pas avec la déclaration de copie. Comment puis-je faire correspondre et transformer les balises namespaced?

+0

Il serait utile si vous avez posté un exemple de XML et/ou le message d'erreur exact. –

+0

Ne nous montrez pas le code qui fonctionne, montrez-nous le code qui ne fonctionne pas, et dites-nous exactement comment cela échoue. Je suis sûr que le message est plus spécifique que "quelque chose ne va pas avec la déclaration de copie". –

+0

Le message d'erreur a été: XSLTProcessor :: transformToXml(): erreur d'exécution: xxx.xsl ligne zz élément copie. Le code qui n'a pas fonctionné était juste le code ci-dessus sans les caractères de commentaire '! -' et '-'. Mais le problème est résolu maintenant, merci. – stofl

Répondre

2

Vous obtenez probablement une erreur car l'élément abc:set a des attributs et votre modèle correspondant à abc:set génère des attributs "nus" qui ne sont pas attachés à un élément.

Puisque vous ne copiez pas l'élément abc:set (ou la création d'un élément) dans le match de modèle pour abc:set, lorsque le apply-templates intérieur de ce modèle applique les modèles à sélectionné abc:set/@* et abc:set/node(), les attributs correspondent au modèle d'identité et sera copié vers l'avant.

Vous pouvez vérifier si tel est le problème en prenant le @* de l'instruction select pour la apply-templates, comme ceci:

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

Le modèle ci-dessus ne traitera les nœuds enfants de abc:set.

Si votre intention était simplement de copier le abc:set, vous n'avez pas besoin d'un modèle spécifique correspondant à cet élément. Le modèle d'identité va correspondre et gérer cela pour vous.

+0

Merci beaucoup. C'était le problème! – stofl

2

Je ne sais pas exactement ce que vous essayez d'atteindre. Votre question est un peu abstraite. Cependant, votre attribut de correspondance est correct. Mais il n'y a pas de différence en ce moment à ce que:

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

fait et à ce que cela:

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

fait. Si vous voulez juste tout copier alors le premier modèle suffirait, y compris les balises avec des espaces de noms. Sinon, je suppose que vous auriez besoin de faire quelque chose différemment en faisant correspondre votre balise namespaced. Si c'est le cas, vous n'avez plus besoin d'appeler le modèle de correspondance d'identité. par exemple. :

<!--Do something with abc:set--> 
<xsl:template match="abc:set"> 
    <setchanged name="{@name}"/> 
</xsl:template> 

Soyez assuré que cela va correspondre à tous les balises abc: set et leur appliquer la transformation.

+0

Merci, ça m'a aidé aussi. – stofl

+0

Vous êtes les bienvenus. – FailedDev

2

Si vous voulez vraiment supprimer l'élément abc:set mais garder le sous-arbre dont il est la racine, puis remplacez:

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

avec:

<xsl:template match="abc:set"> 
    <xsl:apply-templates/>  
</xsl:template> 

Votre code d'origine entraînerait des erreurs si l'élément correspondant a des attributs, car la règle d'identité les copiera, probablement en plus de la création d'un élément. être une tentative de produire des attributs n'appartenant à aucun élément. Tout processeur XSLT est obligé de signaler une erreur dans ce cas.

Le code de remplacement ne traite aucun des attributs de l'élément correspondant abc:set.

+0

Oui, ça m'a aidé. Maintenant ça marche. Je vous remercie. Je pensais avoir besoin de l'attribut select. – stofl