2

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

4

2 回答 2

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 方法进行分组

于 2012-05-24T12:03:00.393 回答
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>
于 2012-05-24T06:29:49.800 回答