xsl聚合或子查询

时间:2012-05-23 20:00:37

标签: html xml xslt

对于具有以下结构的XML文件

 <?xml version="1.0" encoding="UTF-8">
 <farm xmlns:my="mynamespace.com" >
   <pen>
    <sheep> 3 </sheep>
    <cow> 3</cow>
    <pig> 2</pig>
    <chicken> 5</chicken>
   </pen>
  <pen>
    <sheep> 12 </sheep>
    <cow> 1</cow>
    <pig> 2</pig>
    <chicken> 4</chicken>
   </pen>
  <pen>
    <sheep> 4 </sheep>
    <cow> 4</cow>
    <pig> 1</pig>
    <chicken> 2</chicken>
   </pen>
 </farm>

我有一个xsl样式表,循环遍历每个笔节点(for-each),为每种动物类型生成一个id,即绵羊,牛,猪和鸡,并计算总数。生成如下表格

ANIMAL   | VALUE
-----------------
pig      |  5
cow      |  8
sheep    | 19
chickens | 11

现在我希望通过值列对此结果集进行排序 是否可以使用XSL执行等效的子查询?

2 个答案:

答案 0 :(得分:3)

此XSLT 1.0转换

<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="kAnimalByName" match="pen/*" use="name()"/>

 <xsl:template match="/*">
     <table border="1">
      <thead>
          <tr>
           <td>Animal</td>
           <td>Total</td>
          </tr>
      </thead>
      <tbody>
       <xsl:apply-templates select=
        "/*/pen/*
           [generate-id()
           =
            generate-id(key('kAnimalByName', name())[1])
            ]">
         <xsl:sort select="sum(/*/pen/*[name() = name(current())])"
                   data-type="number"/>
       </xsl:apply-templates>
      </tbody>
     </table>
 </xsl:template>

 <xsl:template match="pen/*">
  <tr>
   <td><xsl:value-of select="name()"/></td>
   <td>
     <xsl:value-of select="sum(/*/pen/*[name() = name(current())])"/>
   </td>
  </tr>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时:

<farm xmlns:my="mynamespace.com" >
    <pen>
        <sheep> 3 </sheep>
        <cow> 3</cow>
        <pig> 2</pig>
        <chicken> 5</chicken>
    </pen>
    <pen>
        <sheep> 12 </sheep>
        <cow> 1</cow>
        <pig> 2</pig>
        <chicken> 4</chicken>
    </pen>
    <pen>
        <sheep> 4 </sheep>
        <cow> 4</cow>
        <pig> 1</pig>
        <chicken> 2</chicken>
    </pen>
</farm>

会产生想要的正确结果:

<table border="1">
   <thead>
      <tr>
         <td>Animal</td>
         <td>Total</td>
      </tr>
   </thead>
   <tbody>
      <tr>
         <td>pig</td>
         <td>5</td>
      </tr>
      <tr>
         <td>cow</td>
         <td>8</td>
      </tr>
      <tr>
         <td>chicken</td>
         <td>11</td>
      </tr>
      <tr>
         <td>sheep</td>
         <td>19</td>
      </tr>
   </tbody>
</table>

解释:正确使用 Muenchian method for grouping

答案 1 :(得分:1)

此样式表......

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="html" indent="yes" encoding="UTF-8"
   doctype-public="-//W3C//DTD HTML 4.01//EN"
   doctype-system="http://www.w3.org/TR/html4/strict.dtd" />

 <xsl:template match="/">
 <HTML><head><title>Summary of Chattels</title></head>
 <BODY>
 <xsl:choose>
  <xsl:when test="count( farm/pen/*[namespace-uri()='']) != 0">
   <table style="border: 1px solid #808080">
    <tr><th>ANIMAL</th> <th>VALUE</th></tr>
    <xsl:for-each-group select="farm/pen/*[namespace-uri()='']" group-by="local-name()" >
      <xsl:sort select="sum( current-group())" data-type="number" order="ascending" />
      <xsl:sort select="local-name()" data-type="text" order="ascending" />
      <tr><td><xsl:value-of select="local-name()" /></td>
          <td><xsl:value-of select="sum( current-group())" /></td></tr>
    </xsl:for-each-group>
   </table>
  </xsl:when>
  <xsl:otherwise>
   <p>There are no chattels.</p>
  </xsl:otherwise>
 </xsl:choose>   
 </BODY>
 </HTML>
 </xsl:template>

</xsl:stylesheet>

将为给定的示例文件生成此html ...

<!DOCTYPE html
  PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<HTML>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Summary of Chattels</title>
   </head>
   <BODY>
      <table style="border: 1px solid #808080">
         <tr>
            <th>ANIMAL</th>
            <th>VALUE</th>
         </tr>
         <tr>
            <td>pig</td>
            <td>5</td>
         </tr>
         <tr>
            <td>cow</td>
            <td>8</td>
         </tr>
         <tr>
            <td>chicken</td>
            <td>11</td>
         </tr>
         <tr>
            <td>sheep</td>
            <td>19</td>
         </tr>
      </table>
   </BODY>
</HTML>

如果您想要文本输出,那么调整文本将是一项微不足道的练习。

如果服务器场为空,您将获得此输出...

<!DOCTYPE html
  PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<HTML>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Summary of Chattels</title>
   </head>
   <BODY>
      <p>There are no chattels.</p>
   </BODY>
</HTML>