在XSLT 1.0中对元素进行分组并排除此分组中的一些元素

时间:2014-07-10 08:07:51

标签: xslt xslt-1.0

我有以下输入XML:

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <row>
        <code>EXCLUDE</code>
        <value>VALUE1</value>
    </row>
    <row>
        <code>EXCLUDEALSO</code>
        <value>VALUE2</value>
    </row>
    <row>
        <code>NUMBER</code>
        <value>001</value>
    </row>
    <row>
        <code>FROM</code>
        <value>NAMELINE_FROM</value>
    </row>
    <row>
        <code>TO</code>
        <value>NAMELINE_TO</value>
    </row>
    <row>
        <code>NUMBER</code>
        <value>002</value>
    </row>
    <row>
        <code>TO</code>
        <value>NAMELINE_TO</value>
    </row>
    <row>
        <code>NUMBER</code>
        <value>003</value>
    </row>
    <row>
        <code>FROM</code>
        <value>NAMELINE_FROM</value>
    </row>
    <row>
        <code>NUMBER</code>
        <value>004</value>
    </row>
    <row>
        <code>TO</code>
        <value>NAMELINE</value>
    </row>
    <row>
        <code>FROM</code>
        <value>NAMELINE</value>
    </row>
    <row>
        <code>EXCLUDE</code>
        <value>VALUE1</value>
    </row>
    <row>
        <code>EXCLUDEALSO</code>
        <value>VALUE2</value>
    </row>
</data>

需要将其转换为以下XML:

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <row>
        <code>EXCLUDE</code>
        <value>VALUE1</value>
    </row>
    <row>
        <code>EXCLUDEALSO</code>
        <value>VALUE2</value>
    </row>
    <group>
        <row>
            <code>NUMBER</code>
            <value>001</value>
        </row>
        <row>
            <code>FROM</code>
            <value>NAMELINE_FROM</value>
        </row>
        <row>
            <code>TO</code>
            <value>NAMELINE_TO</value>
        </row>
    </group>
    <group>
        <row>
            <code>NUMBER</code>
            <value>002</value>
        </row>
        <row>
            <code>TO</code>
            <value>NAMELINE_TO</value>
        </row>
    </group>
    <group>
        <row>
            <code>NUMBER</code>
            <value>003</value>
        </row>
        <row>
            <code>FROM</code>
            <value>NAMELINE_FROM</value>
        </row>
    </group>
    <group>
        <row>
            <code>NUMBER</code>
            <value>004</value>
        </row>
        <row>
            <code>TO</code>
            <value>NAMELINE</value>
        </row>
        <row>
            <code>FROM</code>
            <value>NAMELINE</value>
        </row>
    </group>
    <row>
        <code>EXCLUDE</code>
        <value>VALUE1</value>
    </row>
    <row>
        <code>EXCLUDEALSO</code>
        <value>VALUE2</value>
    </row>
</data>

要应用的规则:

  1. 需要从分组中排除某些行。这些行是没有代码NUMBERFROMTO的行。
  2. 当代码NUMBER出现时,新组启动
  3. FROMTO的顺序可以不同
  4. 必须排除的行将始终位于要分组的代码的前面和/或末尾。它永远不会出现在两者之间。
  5. 在XSLT 2.0中,这很容易,我有解决方案,但在XSLT 1.0中,我不知道从哪里开始。

1 个答案:

答案 0 :(得分:1)

这是一个样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:output indent="yes"/>
   <xsl:strip-space elements="*"/>

   <xsl:key name="group" match="row[code = 'TO' or code = 'FROM']" use="generate-id(preceding-sibling::row[code = 'NUMBER'][1])"/>
   <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="row[code = 'NUMBER']">
      <group>
        <xsl:copy-of select=". | key('group', generate-id())"/>
      </group>
    </xsl:template>

    <xsl:template match="row[code = 'FROM' or code = 'TO']"/>

</xsl:stylesheet>