Xml 如何在XSLT1.0中使用XSLT2.0中的分组功能?

Xml 如何在XSLT1.0中使用XSLT2.0中的分组功能?,xml,xslt,xslt-1.0,xslt-2.0,xslt-grouping,Xml,Xslt,Xslt 1.0,Xslt 2.0,Xslt Grouping,我试图在XSLT1.0中使用XSLT2.0中的GROUPBY功能。我的代码使用XSLT2.0,但我的处理器不处理XSLT2.0。因此,我需要一些在XSLT1.0中使用GROUPBY函数的帮助 XML数据: <table> <row> <month>03</month> <year>2016</

我试图在XSLT1.0中使用XSLT2.0中的GROUPBY功能。我的代码使用XSLT2.0,但我的处理器不处理XSLT2.0。因此,我需要一些在XSLT1.0中使用GROUPBY函数的帮助

XML数据:

              <table>
                <row>
                    <month>03</month>
                    <year>2016</year>
                    <Id>10101</Id>
                    <Number>1</Number>
                    <code>A2004</code>
                </row>
                <row>
                    <month>03</month>
                    <year>2016</year>
                    <type>A</type>
                    <Id>10101</Id>
                    <Number>2</Number>
                    <code>A2004</code>
                </row>
                <row>
                    <month>04</month>
                    <year>2015</year>
                    <Id>10122</Id>
                    <Number>1</Number>
                    <code>A2004</code>
                </row>
            </table>
我试图在ID级别和其中的数字上对xml进行分组

            <test>
                <xsl:for-each-group select="$table" group-by="Id">
                    <xsl:variable name="var2_resultof_group_items" as="item()+" select="current-group()"/>
                    </xsl:variable>
                    <row>
                        <xsl:attribute name="Id">
                            <xsl:value-of select="normalize-space(current-grouping-key())"/>
                        </xsl:attribute>
                        <xsl:for-each select="$var2_resultof_group_items">
                            <xsl:attribute name="month">
                                <xsl:value-of select="month"/>
                            </xsl:attribute>
                        </xsl:for-each>
                        <xsl:for-each select="$var2_resultof_group_items">
                            <xsl:attribute name="year">
                                <xsl:value-of select="year"/>
                            </xsl:attribute>
                        </xsl:for-each>
                        <xsl:for-each-group select="$var2_resultof_group_items" group-by="Number">
                            <xsl:variable name="var1_resultof_group_items" as="item()+" select="current-group()"/>
                            <line>
                                <xsl:attribute name="number" select="current-grouping-key()"/>
                                <xsl:for-each select="$var1_resultof_group_items">
                                    <xsl:attribute name="code">
                                        <xsl:value-of select="code"/>
                                    </xsl:attribute>
                                </xsl:for-each>
                            </line>
                        </xsl:for-each-group>
                    </row>
                </xsl:for-each-group>
            </test>

这是我使用XSLT2.0代码得到的输出(期望的输出),但我不确定如何使用XSLT1.0执行此操作

            <test>
                <row Id="10101" month="03" year="2016">
                    <line Number="1" code="A2004"/>
                    <line Number="2" code="A2004"/>
                </row>
                <row Id="10122" month="04" year="2015">
                    <line Number="1" code="A2004"/>
                </row>
            </test>

我可以使用XLST 1.0获得以下输出,但我不确定如何实现ID分组以及其中的数字分组:

            <test>
                <row Id="10101" month="03" year="2016">
                    <line Number="1" code="A2004"/>
                </row>
                <row Id="10101" month="03" year="2016">
                    <line Number="2" code="A2004"/>
                </row>
                <row Id="10122" month="04" year="2015">
                    <line Number="1" code="A2004"/>
                </row>
            </test>

您可以尝试此XSLT 1.0解决方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
    <xsl:key name="kid" match="row" use="Id"/>
     <xsl:template match="table">
        <test>
            <xsl:for-each select="row [ 
                                count ( key('kid',./Id)[1] | . ) = 1 ]">

                <xsl:variable name="this" select="."/>
                <row>
                    <xsl:attribute name="Id">
                      <xsl:value-of select="Id"/>
                    </xsl:attribute>
                    <xsl:attribute name="month">
                      <xsl:value-of select="month"/>
                    </xsl:attribute>
                    <xsl:attribute name="year">
                        <xsl:value-of select="year"/>
                    </xsl:attribute>
                    <xsl:for-each select="key('kid', $this/Id)">
                        <line>
                           <xsl:attribute name="number" >
                               <xsl:value-of  select="Number"/>
                           </xsl:attribute>
                            <xsl:attribute name="code">
                               <xsl:value-of select="code"/>
                            </xsl:attribute>
                        </line>
                    </xsl:for-each>
              </row>
          </xsl:for-each>
        </test>
    </xsl:template>
</xsl:stylesheet>

具有以下输出:

<test>
  <row Id="10101" month="03" year="2016">
    <line number="1" code="A2004"/>
    <line number="2" code="A2004"/>
  </row>
  <row Id="10122" month="04" year="2015">
    <line number="1" code="A2004"/>
  </row>
</test>

这里有一个更简单、更短、几乎完全采用“推送”方式的解决方案

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:key name="kRowById" match="row" use="Id"/>

  <xsl:template match="/*">
    <test>
      <xsl:apply-templates/>
    </test>
  </xsl:template>

  <xsl:template match="row[generate-id() = generate-id(key('kRowById', Id)[1])]">
    <row id="{Id}">
      <xsl:apply-templates select="key('kRowById', Id)" mode="inGroup"/>
    </row>
  </xsl:template>

  <xsl:template match="row" mode="inGroup">
    <line Number="{Number}" code="{code}"/>
  </xsl:template>
  <xsl:template match="text()"/>
</xsl:stylesheet>
<test>
   <row id="10101">
      <line Number="1" code="A2004"/>
      <line Number="2" code="A2004"/>
   </row>
   <row id="10122">
      <line Number="1" code="A2004"/>
   </row>
</test>
生成所需的正确结果

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:key name="kRowById" match="row" use="Id"/>

  <xsl:template match="/*">
    <test>
      <xsl:apply-templates/>
    </test>
  </xsl:template>

  <xsl:template match="row[generate-id() = generate-id(key('kRowById', Id)[1])]">
    <row id="{Id}">
      <xsl:apply-templates select="key('kRowById', Id)" mode="inGroup"/>
    </row>
  </xsl:template>

  <xsl:template match="row" mode="inGroup">
    <line Number="{Number}" code="{code}"/>
  </xsl:template>
  <xsl:template match="text()"/>
</xsl:stylesheet>
<test>
   <row id="10101">
      <line Number="1" code="A2004"/>
      <line Number="2" code="A2004"/>
   </row>
   <row id="10122">
      <line Number="1" code="A2004"/>
   </row>
</test>

说明

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:key name="kRowById" match="row" use="Id"/>

  <xsl:template match="/*">
    <test>
      <xsl:apply-templates/>
    </test>
  </xsl:template>

  <xsl:template match="row[generate-id() = generate-id(key('kRowById', Id)[1])]">
    <row id="{Id}">
      <xsl:apply-templates select="key('kRowById', Id)" mode="inGroup"/>
    </row>
  </xsl:template>

  <xsl:template match="row" mode="inGroup">
    <line Number="{Number}" code="{code}"/>
  </xsl:template>
  <xsl:template match="text()"/>
</xsl:stylesheet>
<test>
   <row id="10101">
      <line Number="1" code="A2004"/>
      <line Number="2" code="A2004"/>
   </row>
   <row id="10122">
      <line Number="1" code="A2004"/>
   </row>
</test>
  • 慕尼黑集团

  • 使用标准XSLT函数
    generate-id()
    进行节点标识比较

  • 使用AVT(属性值模板)

  • 使用模式

  • 使用XSLT内置(也称为“默认”)模板


  • 从这里开始:然后看看这里贴在SO上的许多明钦族分组的例子。这非常有效。你能给我解释一下这个表达式是干什么的吗谢谢!看看(正如michael.hor257k指出的)。查看由两个节点组成的节点集中是否有一个或两个节点-节点不能在节点集中重复,因此,如果节点集中只有一个节点,那么它们必须是相同的节点,这对于解决方案来说非常困难。我仍然对push样式表很熟悉,这对我来说是一个很好的例子。不过我有一个问题,我的要求之一是将'code'变量的最小字符串长度设置为'5'。当源代码向我提供空字符串时,有没有一种简单的方法可以在push样式中实现这一点?类似XSLT1.0的东西?