2017-06-12 105 views
1

我希望以特殊方式對輸出進行分組,也許使用muenchian分組?但我堅持使用XSLT(muenchian分組?)對HTML輸出進行分組

下面是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

請減少的例子,只什麼是必要證明問題 - 請參閱:[mcve]。 –

+0

這已經從一個更大的文件中減少了。我認爲這裏的一切都是必要的。 – GeoffreyB

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

工作完美!非常感謝你 :) – GeoffreyB