如何使用xsl 1.0查找最小值和最大值?

时间:2012-10-11 09:05:21

标签: xslt xslt-1.0

file_1.xml

<productlist>
    <items>
        <item>Pen</item>
        <price>8</item>
    </items>
    <items>
        <item>Pen</item>
        <price>5</item>
    </items>
    <items>
        <item>Pen</item>
        <price>10</item>
    </items>
    <items>
        <item>Bag</item>
        <price>15</item>
    </items>
    <items>
        <item>Bag</item>
        <price>22</item>
    </items>
    <items>
        <item>Bag</item>
        <price>20</item>
    </items>
</productlist>

file_2.xml

<productlist>
    <items>
        <item>Pen</item>
    </items>
    <items>
        <item>Bag</item>
    </items>
</productlist>

使用xsl 1.0

需要输出如下最大值和最小值
<productlist>
    <items>
        <item>Pen</item>
        <min>5</min>
        <max>10</max>
    </items>
    <items>
        <item>Bag</item>
        <min>15</min>
        <max>22</max>
    </items>
</productlist>

2 个答案:

答案 0 :(得分:7)

排序然后取第一个作为最小值,最后一个作为最大值:

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

<xsl:param name="data-url" select="'file_1.xml'"/>
<xsl:variable name="data-doc" select="document($data-url)"/>

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

<xsl:key name="k1" match="items" use="item"/>

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

<xsl:template match="items">
  <xsl:variable name="this" select="."/>
  <xsl:copy>
    <xsl:copy-of select="item"/>
    <xsl:for-each select="$data-doc">
      <xsl:for-each select="key('k1', $this/item)">
         <xsl:sort select="price" data-type="number" order="ascending"/>
         <xsl:if test="position() = 1">
           <min>
             <xsl:value-of select="price"/>
           </min>
         </xsl:if>
         <xsl:if test="position() = last()">
           <max>
             <xsl:value-of select="price"/>
           </max>
         </xsl:if>
       </xsl:for-each>
     </xsl:for-each>
   </xsl:copy>
 </xsl:template>

</xsl:stylesheet>

当我在输入文档上使用Saxon 6.5.5上面的样式表时

<productlist>
    <items>
        <item>Pen</item>
    </items>
    <items>
        <item>Bag</item>
    </items>
</productlist>

其他文件是

<productlist>
    <items>
        <item>Pen</item>
        <price>8</price>
    </items>
    <items>
        <item>Pen</item>
        <price>5</price>
    </items>
    <items>
        <item>Pen</item>
        <price>10</price>
    </items>
    <items>
        <item>Bag</item>
        <price>15</price>
    </items>
    <items>
        <item>Bag</item>
        <price>22</price>
    </items>
    <items>
        <item>Bag</item>
        <price>20</price>
    </items>
</productlist>

我得到想要的结果

<productlist>
   <items>
      <item>Pen</item>
      <min>5</min>
      <max>10</max>
   </items>
   <items>
      <item>Bag</item>
      <min>15</min>
      <max>22</max>
   </items>
</productlist>

答案 1 :(得分:-1)

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <xsl:apply-templates select="productlist"/>
    </xsl:template>
    <xsl:template match="productlist">
        <productlist>
            <xsl:variable name="intermediate">
                <xsl:for-each-group select="items" group-by="item">
                    <items>
                        <item>
                            <xsl:value-of select="item"/>
                        </item>
                        <prices>
                            <xsl:for-each select="current-group()">
                                <price>
                                    <xsl:value-of select="price"/>
                                </price>
                            </xsl:for-each>
                        </prices>
                    </items>
                </xsl:for-each-group>
            </xsl:variable>
            <xsl:for-each select="$intermediate/items">
                <items>
                    <item>
                        <xsl:value-of select="item"/>
                    </item>
                    <xsl:for-each select="prices">
                        <min>
                            <xsl:value-of select="min(price)"/>
                        </min>
                        <max>
                            <xsl:value-of select="max(price)"/>
                        </max>
                    </xsl:for-each>
                </items>
            </xsl:for-each>
        </productlist>
    </xsl:template>
</xsl:stylesheet>