2011-03-24 7 views
1

Voici mon modèle:transformation XSLT du document XML Document XHTML

<xsl:template name="rec"> 
    <xsl:for-each select="*"> 
    <div class="{local-name()}"> 
     <xsl:for-each select="@*"> 
     <xsl:attribute name="data-{local-name()}"> 
      <xsl:value-of select="."/> 
     </xsl:attribute> 
     </xsl:for-each> 
     <xsl:value-of select="text()" /> 
     <xsl:call-template name="rec" /> 
    </div> 
    </xsl:for-each> 
</xsl:template> 

un document donné comme ceci:

<test> 
    <item value="1">Item 1 Text</item> 
    <item value="2">Item 2 Text</item> 
</test> 

ci-dessus transform se transformer en:

<div class="test"> 
    <div class="item" data-value="1">Item 1 Text</div> 
    <div class="item" data-value="2">Item 2 Text</div> 
</div> 

Le problème que j'ai, c'est que cette transformation ne respecte pas les nœuds de texte correctement, et je n'ai pas assez de fond avec XSLT pour figurer e comment y remédier. Voici le problème: étant donné xml comme ceci:

<para>This is a <emphasis>paragraph</emphasis> people!</para> 

Je voudrais voir la sortie suivante:

<div class="para">This is a <div class="emphasis">paragraph</div> people!</div> 

Le problème est que je ne reçois pas - je reçois ceci:

<div class="para">This is a <div class="emphasis">paragraph</div></div> 

Notez les 'personnes' manquantes nœud de texte. Comment puis-je réparer mon XSLT ci-dessus pour me fournir la sortie dont j'ai besoin?

Répondre

4

Un problème est que

<xsl:value-of select="text()" /> 

sélectionne seulement la valeur du premier nœud de texte enfant, et le sort.

La méthode la plus simple pour ce faire est probablement d'utiliser <xsl:apply-templates> au lieu de <xsl:call-template>.

Alors, au lieu de

<xsl:for-each select="*"> 

et

<xsl:value-of select="text()" /> 

vous pouvez utiliser

<xsl:apply-templates /> 

qui appliquera le modèle approprié à chaque élément enfant et noeud texte, dans l'ordre, non sauter tout.

Voici une mise en œuvre complète:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 

    <xsl:template match="*"> 
     <div class="{local-name()}"> 
     <xsl:for-each select="@*"> 
      <xsl:attribute name="data-{local-name()}"> 
       <xsl:value-of select="."/> 
      </xsl:attribute> 
     </xsl:for-each> 
     <xsl:apply-templates /> 
     </div> 
    </xsl:template> 

</xsl:stylesheet> 

Notez le <xsl:apply-templates/>, qui fonctionne sur tous les enfants du nœud de contexte, y compris les nœuds de texte, par défaut, en l'absence d'un attribut select explicite.

Un modèle par défaut est utilisé pour les nœuds de texte. Ce modèle les copie simplement à la sortie.

entrée de l'échantillon:

<test> 
    <item value="1">Item 1 Text</item> 
    <item value="2">Item 2 Text</item> 
    <para>This is a <emphasis>paragraph</emphasis> people!</para> 
</test> 

produit la sortie désirée:

<div class="test"> 
    <div class="item" data-value="1">Item 1 Text</div> 
    <div class="item" data-value="2">Item 2 Text</div> 
    <div class="para">This is a <div class="emphasis">paragraph</div> people!</div> 
</div> 
+0

Je pense que je vois ce que vous faites ici.=) Cela produit effectivement l'effet que je cherche - merci beaucoup! –

+0

+1 pour une réponse correcte. –

+0

+1 Bonne réponse et bonne explication. –

Questions connexes