2009-07-14 22 views
0

Ich verwende derzeit zwei Stylesheets, um meine beabsichtigte Ausgabe zu erhalten. Das erste Stylesheet (pass1.xsl) erledigt die eigentliche Arbeit, und das zweite Stylesheet (pass2.xsl) entfernt Duplikate bei kleineren Formatierungsupdates.XSLT: Konsolidieren von Stylesheets

Meine Frage ist, ob ich beide Aktionen in einem einzigen Stylesheet durchführen kann.
Wenn ich mir den Inhalt anschaue, bekomme ich nicht den Eindruck, dass ich über xsl: functions arbeiten kann, weil beide Stylesheets Template Matches enthalten, die Konflikte verursachen würden, wenn ich von der zweiten in die erste kopiere. 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> 

Um es zu wiederholen - das Ziel ist nur ein Stylesheet ausführen, um das Endergebnis zu produzieren. Es ist nicht schwer, zwei zu rennen, aber es wäre schön, das nicht zu müssen. Betrachte ich das Kopieren/Einfügen in das Original &, damit es funktioniert, oder sind Importe/enthalten, was ich mir ansehen sollte? Ich hätte lieber nur eine Stylesheet-Datei - um die Wahrscheinlichkeit zu minimieren, dass jemand versehentlich eine unterstützende Datei löscht.

Antwort

1

Sie sollten verschiedene modes für Vorlagen verwenden (dies erfordert mode Attribut zu allen xsl:template und Anweisungen hinzufügen). Dann würde Ihre Vorlage für den Stammknoten im Standardmodus zuerst die Stammvorlage im ersten Modus auslösen und dann das Ergebnis an die Stammvorlage im zweiten Modus übergeben. Dazu benötigen Sie die Möglichkeit, ein Ergebnisbaumfragment (das wird von Elementkonstruktoren erzeugt) als Knotenmenge zu behandeln (auf die Sie Vorlagen anwenden und diese sonst über XPath abfragen können) - dafür gibt es keine Standardmethode , aber exsl:node-set ist ein De-facto-Standard dafür (beachten Sie, dass die vollständige Liste der Prozessoren, die es unterstützen, größer ist als das, was auf dieser Seite ist - zum Beispiel unterstützt .NET XslCompiledTransform es). Also:

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