Сгруппировать вывод HTML с помощью XSLT(muenchian grouping?)

Я хотел бы, чтобы выходные данные были сгруппированы особым образом, возможно, с использованием группировок muenchian? но я застрял

Вот файл XML:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<NTC_PUBLICATION xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test.xsd">
    <SECTION_CONTENT_LIST_ITEM>
        <NM_TORP_NTC>
            <PUBLISH_NUMBER>138</PUBLISH_NUMBER>
            <TERM>Temporary</TERM>
            <NM_CHART_AFFECTED_LIST>
                <CHART_NUM>NZ 21 (INT 641), NZ 522, NZ 5219</CHART_NUM>
            </NM_CHART_AFFECTED_LIST>
        </NM_TORP_NTC>
    </SECTION_CONTENT_LIST_ITEM>
    <SECTION_CONTENT_LIST_ITEM>
        <NM_TORP_NTC>
            <PUBLISH_NUMBER>139</PUBLISH_NUMBER>
            <TERM>Temporary</TERM>
            <NM_CHART_AFFECTED_LIST>
                <CHART_NUM>NZ 522, NZ 5321</CHART_NUM>
            </NM_CHART_AFFECTED_LIST>
        </NM_TORP_NTC>
    </SECTION_CONTENT_LIST_ITEM>
    <SECTION_CONTENT_LIST_ITEM>
        <NM_TORP_NTC>
            <PUBLISH_NUMBER>141</PUBLISH_NUMBER>
            <TERM>Preliminary</TERM>
            <NM_CHART_AFFECTED_LIST>
                <CHART_NUM>NZ 268</CHART_NUM>
            </NM_CHART_AFFECTED_LIST>
        </NM_TORP_NTC>
    </SECTION_CONTENT_LIST_ITEM>
    <SECTION_CONTENT_LIST_ITEM>
        <NM_TORP_NTC>
            <PUBLISH_NUMBER>143</PUBLISH_NUMBER>
            <TERM>Preliminary</TERM>
            <NM_CHART_AFFECTED_LIST>
                <CHART_NUM>NZ 26, NZ 268</CHART_NUM>
            </NM_CHART_AFFECTED_LIST>
        </NM_TORP_NTC>
    </SECTION_CONTENT_LIST_ITEM>
</NTC_PUBLICATION>

А вот таблица стилей XSLT, которая у меня есть:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:set="http://exslt.org/sets" xmlns:exslt="http://exslt.org/common" exclude-result-prefixes="msxsl exslt">
    <xsl:output method="html" encoding="UTF-8" indent="yes"
        doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
        doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"/>
    <xsl:key name="item" match="item" use="@chart"/>
    <xsl:template match="/">
        <div>
            <xsl:variable name="result">
                <xsl:for-each select="//NM_TORP_NTC">
                    <xsl:call-template name="split">
                        <xsl:with-param name="notice" select="PUBLISH_NUMBER"/>
                        <xsl:with-param name="string" select="NM_CHART_AFFECTED_LIST/CHART_NUM"/>
                        <xsl:with-param name="term" select="TERM"/>
                    </xsl:call-template>
                </xsl:for-each>
            </xsl:variable>
            <xsl:copy-of select="$result"/>
            <table style="padding-left:200px;align:center;">
                <xsl:choose>
                    <xsl:when test="function-available('msxsl:node-set')">
                        <xsl:call-template name="sub-class">
                            <xsl:with-param name="result" select="msxsl:node-set($result)"/>
                        </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:call-template name="sub-class">
                            <xsl:with-param name="result" select="exslt:node-set($result)"/>
                        </xsl:call-template>
                    </xsl:otherwise>
                </xsl:choose>
            </table>
            <!-- Apply the templates for each Notice -->
            <xsl:apply-templates select="SECTION_CONTENT_LIST_ITEM/NM_TORP_NTC"/>
        </div>
    </xsl:template>

    <xsl:template name="split">
        <xsl:param name="notice"/>
        <xsl:param name="string"/>
        <xsl:param name="term"/>
        <xsl:if test="substring-after($string,',')!=''">
            <item>
                <xsl:attribute name="notice">
                    <xsl:value-of select="$notice"/>
                </xsl:attribute>
                <xsl:attribute name="chart">
                    <xsl:value-of select="substring-before($string,',')"/>
                </xsl:attribute>
                <xsl:attribute name="term">
                    <xsl:value-of select="$term"/>
                </xsl:attribute>
            </item>
        </xsl:if>
        <xsl:choose>
            <xsl:when test="substring-after($string,',')!=''">
                <xsl:call-template name="split">
                    <xsl:with-param name="notice" select="$notice"/>
                    <xsl:with-param name="string" select="substring-after($string,',')"/>
                    <xsl:with-param name="term" select="$term"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="not(contains($string,','))">
                <item>
                    <xsl:attribute name="notice">
                        <xsl:value-of select="$notice"/>
                    </xsl:attribute>
                    <xsl:attribute name="chart">
                        <xsl:value-of select="$string"/>
                    </xsl:attribute>
                    <xsl:attribute name="term">
                        <xsl:value-of select="$term"/>
                    </xsl:attribute>
                </item>
            </xsl:when>
        </xsl:choose>
    </xsl:template>

    <xsl:template name="sub-class">
        <xsl:param name="result"/>
        <xsl:for-each select="$result/item[count(. | key('item', @chart)[1]) = 1]">
            <xsl:sort select="@chart" data-type="text" order="ascending"/>
            <tr>
                <td>
                    <xsl:value-of select="@chart"/>
                </td>
                <td>
                    <xsl:for-each select="key('item', @chart)">
                        <xsl:sort select="@notice" data-type="number"/>
                        <xsl:variable name="pos" select="position()"/>
                        <xsl:if test="$pos!=1">
                            <xsl:text>, </xsl:text>
                        </xsl:if>
                        <xsl:value-of select="@notice"/><xsl:text> </xsl:text>
                        <xsl:if test="@term='Temporary'">
                            <xsl:text>(T)</xsl:text>
                        </xsl:if>
                        <xsl:if test="@term='Preliminary'">
                            <xsl:text>(P)</xsl:text>
                        </xsl:if>
                    </xsl:for-each>
                </td>
            </tr>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

В настоящее время вывод выглядит так ((T) для временного и (P) для предварительного):

NZ 268     143 (P)
NZ 5219    138 (T)
NZ 522     138 (T)
NZ 5321    139 (T)
NZ 21      138 (T)
NZ 26      143 (P)
NZ 268     141 (P)
NZ 522     139 (T)

Я хотел бы, чтобы вывод был сгруппирован следующим образом:

NZ 21      138 (T)
NZ 26      143 (P)
NZ 268     141 (P), 143 (P)
NZ 522     139 (T), 141 (P)
NZ 5219    138 (T)
NZ 5321    139 (T)

1 ответ

Решение

Я вижу ваши копии XSLT $result переменная (для отладки), и если вы внимательно посмотрите, есть разница между элементами, которые вы хотите сгруппировать

<item notice="141" chart="NZ 268" term="Preliminary"></item>
....
<item notice="143" chart=" NZ 268" term="Preliminary"></item>

Перед одним из значений chart атрибут, и это означает, что значения отличаются, что касается группирования.

Решение просто в использовании normalize-space обрезать пробелы при создании chart приписывать.

Попробуйте изменить свой split шаблон к этому....

<xsl:template name="split">
    <xsl:param name="notice"/>
    <xsl:param name="string"/>
    <xsl:param name="term"/>
    <xsl:if test="substring-after($string,',')!=''">
        <item>
            <xsl:attribute name="notice">
                <xsl:value-of select="$notice"/>
            </xsl:attribute>
            <xsl:attribute name="chart">
                <xsl:value-of select="normalize-space(substring-before($string,','))"/>
            </xsl:attribute>
            <xsl:attribute name="term">
                <xsl:value-of select="$term"/>
            </xsl:attribute>
        </item>
    </xsl:if>
    <xsl:choose>
        <xsl:when test="substring-after($string,',')!=''">
            <xsl:call-template name="split">
                <xsl:with-param name="notice" select="$notice"/>
                <xsl:with-param name="string" select="substring-after($string,',')"/>
                <xsl:with-param name="term" select="$term"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:when test="not(contains($string,','))">
            <item>
                <xsl:attribute name="notice">
                    <xsl:value-of select="$notice"/>
                </xsl:attribute>
                <xsl:attribute name="chart">
                    <xsl:value-of select="normalize-space($string)"/>
                </xsl:attribute>
                <xsl:attribute name="term">
                    <xsl:value-of select="$term"/>
                </xsl:attribute>
            </item>
        </xsl:when>
    </xsl:choose>
</xsl:template>

Или, может быть, немного упростить это...

<xsl:template name="split">
    <xsl:param name="notice"/>
    <xsl:param name="string"/>
    <xsl:param name="term"/>
    <xsl:if test="normalize-space($string)!=''">
        <item>
            <xsl:attribute name="notice">
                <xsl:value-of select="$notice"/>
            </xsl:attribute>
            <xsl:attribute name="chart">
                <xsl:value-of select="normalize-space(substring-before(concat($string, ','),','))"/>
            </xsl:attribute>
            <xsl:attribute name="term">
                <xsl:value-of select="$term"/>
            </xsl:attribute>
        </item>
    </xsl:if>
    <xsl:if test="contains($string,',')">
        <xsl:call-template name="split">
            <xsl:with-param name="notice" select="$notice"/>
            <xsl:with-param name="string" select="substring-after($string,',')"/>
            <xsl:with-param name="term" select="$term"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>
Другие вопросы по тегам