for-each-group中的XSLT 2.0之前的值

时间:2015-11-05 15:10:14

标签: xml xslt xpath

鉴于这种结构:

<ROOT>
    <MYROW>
        <CATEGORYNAME>first</CATEGORYNAME>
        <DATA>10</DATA>
    </MYROW>
    <MYROW>
        <CATEGORYNAME>second</CATEGORYNAME>
        <DATA>20</DATA>
    </MYROW>
    <MYROW>
        <CATEGORYNAME>second</CATEGORYNAME>
        <DATA>30</DATA>
    </MYROW>
    <MYROW>
        <CATEGORYNAME>first</CATEGORYNAME>
        <DATA>100</DATA>
    </MYROW>
</ROOT>

我正在做这种转变:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:output indent="yes"/>

    <xsl:template match="ROOT">
        <Worksheet>
            <xsl:for-each-group select="MYROW" group-by="CATEGORYNAME">
                <ROW>
                    <CELL>
                        <DATA>
                            <xsl:value-of select="current-grouping-key()"/>
                        </DATA>
                    </CELL>
                </ROW>
                <xsl:apply-templates select="current-group()"/>
            </xsl:for-each-group>
        </Worksheet>
    </xsl:template>

    <xsl:template match="MYROW">
        <ROW>
            <CELL>
                <xsl:value-of select="DATA"/>
            </CELL>
        </ROW>
    </xsl:template>
</xsl:transform>

我想比较&#34; DATA&#34;值与组中的前一个值。我无法获得之前的价值。我试过了:

<xsl:value-of select="preceding-sibling::node()/DATA"/>

,它提供原始XML中的所有先前兄弟节点,而不仅仅是当前组中的。

基本上我想知道是否有办法在分组序列中使用xpath。

预期产出:

<Worksheet>
   <ROW>
      <CELL>
         <DATA>first</DATA>
      </CELL>
   </ROW>
   <ROW>
      <CELL>
         <DATA color = "black">10</DATA>
      </CELL>
   </ROW>
   <ROW>
      <CELL>
         <DATA color = "blue">100</DATA>
      </CELL>
   </ROW>
   <ROW>
      <CELL>
         <DATA color = "red">5</DATA>
      </CELL>
   </ROW>
   <ROW>
      <CELL>
         <DATA>second</DATA>
      </CELL>
   </ROW>
   <ROW>
      <CELL>
         <DATA color = "black">20</DATA>
      </CELL>
   </ROW>
   <ROW>
      <CELL>
         <DATA color = "blue">30</DATA>
      </CELL>
   </ROW>
</Worksheet>

1 个答案:

答案 0 :(得分:1)

假设您显示的是<xsl:apply-templates select="current-group()"/>,然后是<xsl:template match="MYROW">的模板,那么您可以使用

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
   xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">

    <xsl:output indent="yes"/>

    <xsl:template match="ROOT">
        <Worksheet>
            <xsl:for-each-group select="MYROW" group-by="CATEGORYNAME">
                <ROW>
                    <CELL>
                        <DATA>
                            <xsl:value-of select="current-grouping-key()"/>
                        </DATA>
                    </CELL>
                </ROW>
                <xsl:apply-templates select="current-group()"/>
            </xsl:for-each-group>
        </Worksheet>
    </xsl:template>

    <xsl:template match="MYROW">
        <xsl:variable name="pos" select="position()"/>                                                                      
        <xsl:variable name="preceding-group-member" select="current-group()[$pos - 1]"/>
        <xsl:variable name="this-data" select="xs:decimal(DATA)"/>
        <xsl:variable name="preceding-data" select="xs:decimal($preceding-group-member/DATA)"/>
        <ROW>
            <CELL color="{if ($pos eq 1 or $this-data eq $preceding-data) 
                         then 'black' else (if ($this-data gt $preceding-data) then 'blue' else 'red')}">
                <xsl:copy-of select="DATA"/>
            </CELL>
        </ROW>
    </xsl:template>
</xsl:transform>

http://xsltransform.net/pPzifp8/1在线。