xslt选择组的最大值

时间:2013-04-02 01:05:30

标签: sorting xslt max

我需要一个xsl,从任何“object_name”中取出“item_revision_id”的最大值。 从这个输入........

<rows>
    <row>
        <row_element property_name="object_name">pluto</row_element>
        <row_element property_name="description">description of version 00</row_element>
        <row_element property_name="item_revision_id">00</row_element>
    </row>
    <row>
        <row_element property_name="object_name">pluto</row_element>
        <row_element property_name="description">description of version 01</row_element>
        <row_element property_name="item_revision_id">01</row_element>
    </row>
    <row>
        <row_element property_name="object_name">pippo</row_element>
        <row_element property_name="description">description of version 02</row_element>
        <row_element property_name="item_revision_id">02</row_element>
    </row>
    <row>
        <row_element property_name="object_name">pippo</row_element>
        <row_element property_name="description">description of version 00</row_element>
        <row_element property_name="item_revision_id">00</row_element>
    </row>
</rows>

所需的输出是

    <?xml version="1.0" encoding="Windows-1252"?>
    <rows>
    <row>
        <row_element property_name="object_name">pluto</row_element>
        <row_element property_name="description">description of version 01</row_element>
        <row_element property_name="item_revision_id">01</row_element>
    </row>
    <row>
        <row_element property_name="object_name">pippo</row_element>
        <row_element property_name="description">description of version 02</row_element>
        <row_element property_name="item_revision_id">02</row_element>
    </row>
</rows>

我希望得到最大的行元素,而不是创建一个具有混合值的新元素

<?xml version="1.0" encoding="Windows-1252"?>
<rows>
    <row><!-- this is right -->
        <row_element property_name="object_name">pluto</row_element>
        <row_element property_name="description">description of version 01</row_element>
        <row_element property_name="item_revision_id">01</row_element>
    </row>
    <row><!-- this is wrong -->
        <row_element property_name="object_name">pippo</row_element>
        <row_element property_name="description">description of version 00</row_element>
        <row_element property_name="item_revision_id">02</row_element>
    </row>
</rows>

任何帮助?

1 个答案:

答案 0 :(得分:1)

此转化

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kRowByObjName" match="row" use="*[@property_name='object_name']"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match=
 "row[not(generate-id()
         =
          generate-id(key('kRowByObjName', *[@property_name='object_name'])[1])
         )]"/>

<xsl:template match="*[@property_name='item_revision_id']/text()">
  <xsl:for-each select="key('kRowByObjName', ../../*[@property_name='object_name'])">
   <xsl:sort select="*[@property_name='item_revision_id']"
             data-type="number" order="descending"/>
   <xsl:if test="position()=1">
     <xsl:value-of select="*[@property_name='item_revision_id']"/>
   </xsl:if>
  </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时:

<rows>
    <row>
        <row_element property_name="object_name">pluto</row_element>
        <row_element property_name="item_revision_id">00</row_element>
    </row>
    <row>
        <row_element property_name="object_name">pluto</row_element>
        <row_element property_name="item_revision_id">01</row_element>
    </row>
    <row>
        <row_element property_name="object_name">pippo</row_element>
        <row_element property_name="item_revision_id">02</row_element>
    </row>
    <row>
        <row_element property_name="object_name">pippo</row_element>
        <row_element property_name="item_revision_id">00</row_element>
    </row>
</rows>

生成想要的正确结果

<rows>
   <row>
      <row_element property_name="object_name">pluto</row_element>
      <row_element property_name="item_revision_id">01</row_element>
   </row>
   <row>
      <row_element property_name="object_name">pippo</row_element>
      <row_element property_name="item_revision_id">02</row_element>
   </row>
</rows>

<强> II。 XSLT 2.0解决方案:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kRowByObjName" match="row" use="*[@property_name='object_name']"/>

 <xsl:template match="/*">
  <rows>
    <xsl:for-each-group select="row" group-by="*[@property_name='object_name']">
      <row>
        <xsl:sequence select="*[@property_name='object_name']"/>
        <xsl:sequence select=
        "current-group()
          /*[@property_name='item_revision_id'
           and
             . = max(current-group()/*[@property_name='item_revision_id']/number())
            ]"/>
      </row>
    </xsl:for-each-group>
  </rows>
 </xsl:template>
</xsl:stylesheet>