0

次のような入力が与えられます:

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

<code>XSLT 1.0を使用して、隣接する要素を次のようにグループ化するにはどうすればよいですか。

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

これは私が現在持っているものであり、すべてのソースコードが他のすべてのコンテンツ(この例の段落など)の後に1つのセレクターにグループ化されているため、正しく機能しません。

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

1 に答える 1

1

XSLT 1.0でこれを実現するには、次のように、テンプレートを要素の次の隣接要素に一度に1つずつホップします。

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

サンプル入力で実行すると、次のようになります。

<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>
于 2013-01-31T16:54:24.943 に答える