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

나는 이 문제의 첫 번째 부분(범주 변경 사항 감지, first 및 last )을 알아냈습니다 tr. 그러나 XSLT는 끝 또는 시작 태그만 포함하는 XML 조각 방출을 허용하지 않으므로 두 번째 부분을 해결하는 방법을 잘 모르겠습니다. 이 문제 부분. 다음 스니펫은 첫 번째 시도이지만 작동하지 않습니다.

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

관련 정보