2013-01-31 3 views
0

Étant donnée une entrée comme ce qui suit:Appliquer des modèles aux éléments adjacents?

<p>Some information about the proceeding source listing:</p> 
<code language="CSharp"><![CDATA[ ... ]]></code> 
<code language="AnotherLanguage"><![CDATA[ ... ]]></code> 

<p>This is a different example which perhaps applies to just one language:</p> 
<code language="CSharp"><![CDATA[ ... ]]></code> 

<p>Another example:</p> 
<code language="CSharp"><![CDATA[ ... ]]></code> 
<code language="AnotherLanguage"><![CDATA[ ... ]]></code> 
<code language="YetAnotherLanguage"><![CDATA[ ... ]]></code> 

En utilisant XSLT 1.0, comment puis-je groupe l'élément <code> adjacent comme suit:

<p>Some information about the proceeding source listing:</p> 
<div class="source-selector"> 
    <ul class="tabs"> 
     <li class="tab" data-language="CSharp">CSharp</li> 
     <li class="tab" data-language="AnotherLanguage">AnotherLanguage</li> 
    </ul> 
    <div data-language="CSharp"> 
     <pre>...</pre> 
    </div> 
    <div data-language="AnotherLanguage"> 
     <pre>...</pre> 
    </div> 
</div> 

<p>This is a different example which perhaps applies to just one language:</p> 
<div class="source-selector"> 
    <ul class="tabs"> 
     <li class="tab" data-language="CSharp">CSharp</li> 
    </ul> 
    <div data-language="CSharp"> 
     <pre>...</pre> 
    </div> 
</div> 

<p>Another example:</p> 
<div class="source-selector"> 
    <ul class="tabs"> 
     <li class="tab" data-language="CSharp">CSharp</li> 
     <li class="tab" data-language="AnotherLanguage">AnotherLanguage</li> 
     <li class="tab" data-language="YetAnotherLanguage">YetAnotherLanguage</li> 
    </ul> 
    <div data-language="CSharp"> 
     <pre>...</pre> 
    </div> 
    <div data-language="AnotherLanguage"> 
     <pre>...</pre> 
    </div> 
    <div data-language="YetAnotherLanguage"> 
     <pre>...</pre> 
    </div> 
</div> 

C'est ce que j'ai au moment qui ne fonctionne pas correctement parce que tout le code source est groupé dans un seul sélecteur après tout autre contenu (comme les paragraphes dans cet exemple).

<!-- Display paragraphs first --> 
<xsl:apply-templates select="*[not(name() = 'code')]"/> 

<!-- Display consecutive source code within selector --> 
<div class="source-selector"> 
    <ul class="tabs"> 
    <xsl:for-each select="code"> 
     <li class="tab" data-language="{@language}"><include item="{@language}Label"/></li> 
    </xsl:for-each> 
    </ul> 
<xsl:for-each select="code"> 
    <div data-language="{@language}"> 
     <pre><xsl:copy-of select="node()"/></pre> 
    </div> 
</xsl:for-each> 
</div> 

Répondre

1

Vous pouvez accomplir cela en XSLT 1.0 en ayant des modèles SAUT voisins d'un à la fois des éléments, comme ceci:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/*"> 
    <div> 
     <xsl:apply-templates select="*[not(self::code)]" /> 
    </div> 
    </xsl:template> 

    <xsl:template match="/*/*[not(self::code)]"> 
    <xsl:copy-of select="."/> 
    <!-- Select the next neighbor element, but only if it is a <code> --> 
    <xsl:variable name="firstCode" select="following-sibling::*[1][self::code]" /> 
    <div class="source-selector"> 
     <!-- Skip the part with the <ul> if there are no <code> neighbors--> 
     <xsl:if test="$firstCode"> 
     <ul> 
      <xsl:apply-templates select="$firstCode" mode="list" /> 
     </ul> 
     <xsl:apply-templates select="$firstCode" mode="samples" /> 
     </xsl:if> 
    </div> 
    </xsl:template> 

    <xsl:template match="code" mode="list"> 
    <li class="tab" data-language="{@language}"> 
     <xsl:value-of select="@language"/> 
    </li> 
    <!-- Apply this template to the next neighbor, if it is a <code> --> 
    <xsl:apply-templates select="following-sibling::*[1][self::code]" mode="list" /> 
    </xsl:template> 

    <xsl:template match="code" mode="samples"> 
    <div data-language="{@language}"> 
     <pre> 
     <xsl:value-of select="string(.)"/> 
     </pre> 
    </div> 
    <!-- Apply this template to the next neighbor, if it is a <code> --> 
    <xsl:apply-templates 
         select="following-sibling::*[1][self::code]" mode="samples" /> 
    </xsl:template> 

</xsl:stylesheet> 

Lorsqu'il est exécuté sur votre entrée de l'échantillon, ce produit:

<div> 
    <p>Some information about the proceeding source listing:</p> 
    <div class="source-selector"> 
    <ul> 
     <li class="tab" data-language="CSharp">CSharp</li> 
     <li class="tab" data-language="AnotherLanguage">AnotherLanguage</li> 
    </ul> 
    <div data-language="CSharp"> 
     <pre> ... </pre> 
    </div> 
    <div data-language="AnotherLanguage"> 
     <pre> ... </pre> 
    </div> 
    </div> 
    <p>This is a different example which perhaps applies to just one language:</p> 
    <div class="source-selector"> 
    <ul> 
     <li class="tab" data-language="CSharp">CSharp</li> 
    </ul> 
    <div data-language="CSharp"> 
     <pre> ... </pre> 
    </div> 
    </div> 
    <p>Another example:</p> 
    <div class="source-selector"> 
    <ul> 
     <li class="tab" data-language="CSharp">CSharp</li> 
     <li class="tab" data-language="AnotherLanguage">AnotherLanguage</li> 
     <li class="tab" data-language="YetAnotherLanguage">YetAnotherLanguage</li> 
    </ul> 
    <div data-language="CSharp"> 
     <pre> ... </pre> 
    </div> 
    <div data-language="AnotherLanguage"> 
     <pre> ... </pre> 
    </div> 
    <div data-language="YetAnotherLanguage"> 
     <pre> ... </pre> 
    </div> 
    </div> 
</div> 
+0

Parfait, merci! C'est une technique soignée. –

Questions connexes