2009-07-14 7 views
0

J'utilise actuellement deux feuilles de style pour obtenir la sortie voulue. La première feuille de style (pass1.xsl) effectue le travail réel et la deuxième feuille de style (pass2.xsl) supprime les doublons tout en fournissant des mises à jour de mise en forme mineures.XSLT: consolider les feuilles de style

Ma question est de savoir si je peux effectuer les deux actions dans une seule feuille de style.
Quand je regarde le contenu, je n'ai pas l'impression que je peux via les fonctions xsl: parce que les deux feuilles de style contiennent des correspondances qui seraient en conflit si je copiais/collait de la seconde dans la première. IE:

pass1.xsl:

<xsl:template match="xs:complexType"> 
    <xsl:param name="prefix" />  
    <xs:complexType name="{my:updateName($prefix, @name)}"> 

    <!-- insert xs:sequence ONLY if the child is NOT xs:complexContent --> 
    <xsl:choose> 
     <xsl:when test="*[name()='xs:complexContent']"> 
     <xsl:apply-templates select="node()" /> 
     </xsl:when> 
     <xsl:otherwise> 
     <xs:sequence> 
      <xsl:apply-templates select="node()" /> 
     </xs:sequence>    
     </xsl:otherwise> 
    </xsl:choose> 
    </xs:complexType> 
    <xsl:apply-templates select=".//xs:element" /> 
</xsl:template> 

pass2.xsl:

<xsl:template match="xs:complexType"> 
    <xsl:copy> 
    <xsl:apply-templates select="*|@*"/> 
    </xsl:copy> 
</xsl:template> 

Réitérer - l'objectif est d'exécuter une seule feuille de style pour produire le résultat final. Ce n'est pas difficile de courir deux fois, mais ce serait bien de ne pas avoir à le faire. Suis-je en train de copier/coller dans l'original & pour que cela fonctionne, ou est-ce que les importations/comprend ce que je devrais regarder? Je préférerais n'avoir qu'un seul fichier de feuille de style - pour minimiser les risques de suppression par erreur d'un fichier de support.

Répondre

1

Vous devez utiliser différents modes pour les modèles (cela nécessitera l'ajout de l'attribut mode à toutes les instructions xsl:template et). Ensuite, votre modèle pour le nœud racine en mode par défaut déclencherait d'abord le modèle racine dans le premier mode, puis passerait le résultat de cela au modèle racine dans le second mode. Pour cela, vous aurez besoin de traiter un fragment d'arbre de résultat (produit par les constructeurs d'éléments) comme un ensemble de nœuds (auquel vous pouvez appliquer des modèles et interroger via XPath) - il n'existe pas de méthode standard pour cela , mais exsl:node-set est une norme de fait pour cela (notez que la liste complète des processeurs qui le supportent est plus grande que ce qui est sur cette page - par exemple, .NET XslCompiledTransform le prend en charge). Donc:

<xsl:template match="/"> 
    <xsl:variable name="round1-output"> 
    <xsl:apply-templates select="/" mode="round1" /> 
    </xsl:variable> 
    <xsl:apply-templates select="exsl:node-set($round1-output)" mode="round2" /> 
</xsl:template> 

<xsl:template match="/" mode="round1"> 
    ... 
    <xsl:apply-templates mode="round1" /> 
    ... 
</xsl:template> 

<xsl:template match="/" mode="round2"> 
    ... 
    <xsl:apply-templates mode="round2" /> 
    ... 
</xsl:template> 

... 

<xsl:template match="xs:complexType" mode="round1"> 
    <xsl:param name="prefix" />   
    <xs:complexType name="{my:updateName($prefix, @name)}"> 
    <!-- insert xs:sequence ONLY if the child is NOT xs:complexContent --> 
    <xsl:choose> 
     <xsl:when test="*[name()='xs:complexContent']"> 
     <xsl:apply-templates select="node()" mode="round1"/> 
     </xsl:when> 
     <xsl:otherwise> 
     <xs:sequence> 
      <xsl:apply-templates select="node()" mode="round1"/> 
     </xs:sequence>       
     </xsl:otherwise> 
    </xsl:choose> 
    </xs:complexType> 
    <xsl:apply-templates select=".//xs:element" mode="round1"/> 
</xsl:template> 

<xsl:template match="xs:complexType" mode="round2"> 
    <xsl:copy> 
    <xsl:apply-templates select="*|@*" mode="round2"/> 
    </xsl:copy> 
</xsl:template> 
Questions connexes