2010-05-22 8 views
8

je dois transformer la doc xml suivante:XSLT: noeud du texte intérieur

<a> 
    <b/> 
    <c/> 
    myText 
</a> 

dans ce:

<a> 
    <b/> 
    <c/> 
    differentText 
</a> 

Alors, je l'ai écrit ce document XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" version="1.0" omit-xml-declaration="no" /> 

    <xsl:template match="https://stackoverflow.com/a/text()"> 
    <a> 
     <b/> 
     <c/> 
     differentText 
    </a> 
</xsl:template> 
</xsl:stylesheet> 

Cette chemin, j'obtiens le résultat suivant:

<?xml version="1.0" encoding="utf-8"?> 
<a> 
    <b /><c /> 
    differentText 
</a> 
<a> 
    <b /><c /> 
    differentText 
</a> 
<a> 
    <b /><c /> 
    differentText 
</a> 

Le résultat apparaît répété 3 fois car 3 correspondances sont en cours. Pourquoi? Je pourrais le réparer? Merci

+0

Bonne question (+1). Voir ma réponse pour une meilleure solution, plus simple, qui ne nécessite aucun prédicat dans l'expression de correspondance du modèle spécifique. –

Répondre

8

Ne comptez pas les nœuds de texte whtespace uniquement. Connaître et utiliser l'instruction <xsl:strip-space>.

Cette transformation:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <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="a/text()"> 
    <xsl:text>Diferent text</xsl:text> 
</xsl:template> 
</xsl:stylesheet> 

lorsqu'il est appliqué au document XML fourni, produit le résultat correct voulu.

Pas besoin de prédicats complexes dans l'expression de correspondance du modèle spécifique!

Nous devrions nous efforcer de trouver la solution la plus simple, la plus courte, la plus élégante, la plus lisible et la plus compréhensible qui utilise toute la puissance du langage.

Les chances sont qu'une telle solution soit la plus comprise, la plus facile à implémenter et la plus susceptible d'être optimisée par n'importe quel processeur XSLT, ce qui se traduit par une implémentation plus efficace.

+0

BTW, je ne considère pas '[normalize-space()! = '']' 'Un prédicat particulièrement compliqué. ;) – Tomalak

+0

@Tomalak: nous devrions rechercher la solution la plus simple, la plus courte, la plus élégante, la plus lisible et la plus compréhensible qui utilise toute la puissance du langage. Les chances sont qu'une telle solution soit la mieux comprise, la plus facile à implémenter et la plus susceptible d'être optimisée par n'importe quel processeur XSLT, ce qui se traduira par une implémentation plus efficace. :) –

6

Il sont trois matches, comme le souligne entre crochets:

<a>[ 
    ]<b/>[ 
    ]<c/>[ 
    myText 
]</a> 

Vous voulez quelque chose comme:

<xsl:template match="https://stackoverflow.com/a/text()[normalize-space() != '']"> 
+0

Comme indiqué dans ma réponse, aucun prédicat n'est nécessaire dans l'expression de correspondance. :) –

+4

@Dimitre: Je le sais. Ma réponse fournit le moins de changement possible au code existant. Il est basé sur l'hypothèse que le code réel est plus complexe et que < 'peut provoquer des effets secondaires à d'autres endroits. – Tomalak

+0

@Tomalak: Supposer que ce que l'OP n'a pas dit rend souvent la solution sous-optimale et plus difficile à comprendre, voire confuse. De cette façon, nous pouvons finir par dire tout ce que nous savons sur XSLT - "juste au cas où ..." :) –

Questions connexes