XSLTを使用してその要素を持たない要素をフックで作成する

XSLTを使用してその要素を持たない要素をフックで作成する

XMLに変換し、いくつかの部分に分割する非常に長いHTMLテーブルがあります。

略語ソース:

<html>
<head>
<title>Sample doc</title>
</head>
<body>
<table>
    <tr>
        <th>Category title</th>
        <th>Parameter name</th>
        <th>Level</th>
        <th>Values</th>
        <th>Description</th>
    </tr>
    <tr>
        <td class="category">Category A</td>
        <td class="paramname">Parameter 1</td>
        <td class="lvl">1</td>
        <td class="values">1-100</td>
        <td class="description"><p>The quick brown fox jumped over the lazy dogs.</p></td>
    </tr>
    <tr>
        <td class="category">Category A</td>
        <td class="paramname">Parameter 2</td>
        <td class="lvl">2</td>
        <td class="values">2-200</td>
        <td class="description"><p>Every good boy does fine.</p>
</td>
    </tr>
    <tr>
        <td class="category">Category B</td>
        <td class="paramname">Parameter 3</td>
        <td class="lvl">3</td>
        <td class="values">3-300</td>
        <td class="description"><p>Colorless green ideas sleep furiously.</p></td>
    </tr>
    <tr>
        <td class="category">Category B</td>
        <td class="paramname">Parameter 4</td>
        <td class="lvl">4</td>
        <td class="values">4-400</td>
        <td class="description"><p>This has been a test of the emergency broadcast system.</p></td>
    </tr>
</table>
</body>
</html>

希望の出力:

<xml>
    <section>
        <title>Category A</title>

        <para><emphasis><heading>Parameter Name: Parameter 1</heading></emphasis></para>
        <para>Level: 1</para>
        <para>Values: 1-100</para>
        <para>Description: The quick brown fox jumped over the lazy dogs.</para>

        <para><emphasis><heading>Parameter Name: Parameter 2</heading></emphasis></para>
        <para>Level: 2</para>
        <para>Values: 2-200</para>
        <para>Description: Every good boy does fine.</para>
    </section>
    <section>
        <title>Category B</title>

        <para><emphasis><heading>Parameter Name: Parameter 3</heading></emphasis></para>
        <para>Level: 3</para>
        <para>Values: 3-300</para>
        <para>Description: Colorless green ideas sleep furiously.</para>

        <para><emphasis><heading>Parameter Name: Parameter 4</heading></emphasis></para>
        <para>Level: 4</para>
        <para>Values: 4-400</para>
        <para>Description: This has been a test of the emergency broadcast system.</para>
    </section>
</xml>

問題は、変更が発生したタイミングを検出し、出力ストリームにcategoryこれらのカテゴリを含む要素を作成することです。section

私はこの問題の最初の部分(カテゴリ変更の検出、最初と最後)を見つけましたtr。ただし、XSLTは終了タグまたは開始タグのみを含むXMLフラグメントのリリースを許可しないため、2番目の部分を解決する方法がわかりません。この問題の部分。次のスニペットは最初の試みですが、機能しません。

    <xsl:for-each select="tr">
    <xsl:choose>
        <xsl:when test="tr[1]">
            <section><title><xsl:value-of select="td[@class='category']" /></title>
            <xsl:apply-templates/>
        </xsl:when>
        <xsl:when test="tr[last()]">
            <xsl:apply-templates/></section>
        </xsl:when>
        <xsl:when test="preceding-sibling::tr[1]/td[@class='category'] !=td[@class='category']">
            </section><section><title><xsl:value-of select="td[@class='category']" /></title>
            <xsl:apply-templates/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:apply-templates/>
        </xsl:otherwise>
    </xsl:choose>
    </xsl:for-each><!-- tr -->

カテゴリブレークポイントに達するまで出力をバッファリングする必要があるようです。この時点で、sectionラベルにバッファの内容を含めることができますが、どうすればよいかわかりません。

ベストアンサー1

私はXSLT 2.0を使用していますが、それを理解したので、for-each-groupプロセスは非常に単純化されました。

<xsl:stylesheet 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
    exclude-result-prefixes="xs">

<xsl:template match="/">
<xml>
<xsl:for-each select="//table">
<xsl:for-each-group select="tr" group-by="td[@class='category']" >
    <section><title><xsl:value-of select="td[@class='category']" /></title>
    <xsl:for-each select="current-group()">
        <!-- handling for individual tr omitted -->
        <xsl:apply-templates />
    </xsl:for-each>

    </section>
</xsl:for-each-group>
</xsl:for-each>
</xml>
</xsl:template>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>


</xsl:stylesheet>

おすすめ記事