【问题标题】:xsl aggregate or subqueryxsl 聚合或子查询
【发布时间】:2012-05-23 20:00:37
【问题描述】:

对于具有以下结构的 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 进行子查询的等效操作?

【问题讨论】:

    标签: html xml xslt


    【解决方案1】:

    这个 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

    【讨论】:

      【解决方案2】:

      这个样式表 ...

      <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>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-28
        • 2013-08-04
        • 2019-06-13
        • 1970-01-01
        • 1970-01-01
        • 2021-08-25
        • 2021-07-16
        • 2014-11-06
        相关资源
        最近更新 更多