我希望输出以特殊方式分组,也许使用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)
答案 0 :(得分:2)
我看到你的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>