XSLT 2.0 - 分组和排序 - <xsl:for-each-group>

时间:2017-01-21 09:07:12

标签: xml xslt xslt-2.0 xslt-grouping

我想按照fnlabel的顺序将fnrtoken的脚注组合在一起。 所有fnrtoken应按标签分组。 但如果没有fnlabel的任何脚注在这些脚注之间,则应为该脚注创建新组,并再次启动新组以使用fnlable保留脚注

输入:

<endnotes>
    <footnote fntoken="aasdf" fnrtoken="78hyyj">
        <fnlabel>2</fnlabel>
        <para></para>
    </footnote>
    <footnote fntoken="aasdf" fnrtoken="78jjjj">
        <fnlabel>1</fnlabel>
        <para></para>
    </footnote>
    <footnote fntoken="aasdf" fnrtoken="7900hj">
        <fnlabel>4</fnlabel>
        <para></para>
    </footnote>
    <footnote fntoken="aasdf">
        <fnlabel>3</fnlabel>
        <para></para>
    </footnote>
    <footnote fntoken="aasdf">
        <fnlabel>5</fnlabel>
        <para></para>
    </footnote>
</endnotes>


Output:
<footenotegrp>
    <footnote fntoken="aasdf" fnrtoken="78jjjj">
        <fnlabel>1</fnlabel>
        <para></para>
    </footnote>
    <footnote fntoken="aasdf" fnrtoken="78hyyj">
        <fnlabel>2</fnlabel>
        <para></para>
    </footnote>
</footenotegrp>
<footenotegrp>
    <footnote fntoken="aasdf">
        <fnlabel>3</fnlabel>
        <para></para>
    </footnote>
</footenotegrp>
<footenotegrp>
    <footnote fntoken="aasdf" fnrtoken="7900hj">
        <fnlabel>4</fnlabel>
        <para></para>
    </footnote>
</footenotegrp>
<footenotegrp>
    <footnote fntoken="aasdf">
        <fnlabel>5</fnlabel>
        <para></para>
    </footnote>
</footenotegrp>

1 个答案:

答案 0 :(得分:1)

在我看来,您首先想要排序,然后您想要使用group-adjacent="exists(@fnrtoken)"进行分组:

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

    <xsl:output indent="yes"/>

    <xsl:template match="/*">
        <root>
            <xsl:variable name="sorted" as="element(footnote)*">
                <xsl:perform-sort select="footnote">
                    <xsl:sort select="fnlabel"></xsl:sort>
                </xsl:perform-sort>
            </xsl:variable>
            <xsl:for-each-group select="$sorted" group-adjacent="exists(@fnrtoken)">
                <xsl:choose>
                    <xsl:when test="current-grouping-key()">
                        <footnotegrp>
                            <xsl:copy-of select="current-group()"/>
                        </footnotegrp>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:for-each select="current-group()">
                            <footnotegrp>
                                <xsl:copy-of select="."/>
                            </footnotegrp>
                        </xsl:for-each>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each-group>
        </root>
    </xsl:template>

</xsl:stylesheet>

改变

<?xml version="1.0" encoding="UTF-8"?>
<endnotes>
    <footnote fntoken="aasdf" fnrtoken="78hyyj">
        <fnlabel>2</fnlabel>
        <para></para>
    </footnote>
    <footnote fntoken="aasdf" fnrtoken="78jjjj">
        <fnlabel>1</fnlabel>
        <para></para>
    </footnote>
    <footnote fntoken="aasdf" fnrtoken="7900hj">
        <fnlabel>4</fnlabel>
        <para></para>
    </footnote>
    <footnote fntoken="aasdf">
        <fnlabel>3</fnlabel>
        <para></para>
    </footnote>
    <footnote fntoken="aasdf">
        <fnlabel>5</fnlabel>
        <para></para>
    </footnote>
</endnotes>

进入

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <footnotegrp>
      <footnote fntoken="aasdf" fnrtoken="78jjjj">
               <fnlabel>1</fnlabel>
               <para/>
         </footnote>
      <footnote fntoken="aasdf" fnrtoken="78hyyj">
               <fnlabel>2</fnlabel>
               <para/>
         </footnote>
   </footnotegrp>
   <footnotegrp>
      <footnote fntoken="aasdf">
               <fnlabel>3</fnlabel>
               <para/>
         </footnote>
   </footnotegrp>
   <footnotegrp>
      <footnote fntoken="aasdf" fnrtoken="7900hj">
               <fnlabel>4</fnlabel>
               <para/>
         </footnote>
   </footnotegrp>
   <footnotegrp>
      <footnote fntoken="aasdf">
               <fnlabel>5</fnlabel>
               <para/>
         </footnote>
   </footnotegrp>
</root>