Xsl计数基于Filtered节点

时间:2013-09-18 21:29:31

标签: xslt foreach count xslt-1.0

我有以下xml:

<Activity>
     <item>
        <task>XXX</task>
        <assignto>User1</assignto>
     </item>
     <item>
        <task>YYY</task>
        <assignto>User2</assignto>
     </item>
     <item>
        <task>ZZZ</task>
        <assignto>User1</assignto>
     </item>
     <team>
        <member>User1</member>
        <member>User2</member>
     <team>
</Activity>

我想使用XSL生成团队中每个成员的任务计数。

用户计数
user1- 2
user2-1

到目前为止,我有以下XSL:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
    <table>
       <tr>
           <th>User</th>
           <th>Task Count</th>
       </tr>
       <xsl:for-each select="Activity/team/member">
          <tr>
               <td><xsl:value-of select="node()" /></td>
               <td><xsl:value-of select="count(/Activity/item[assignto='user1'])" /></td>
          </tr>
       </xsl:for-each>
    </table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

到目前为止我硬编码'user1',我想根据每个循环中的当前成员进行过滤。

有人可以帮忙吗?

谢谢,

3 个答案:

答案 0 :(得分:0)

在这里,将成员存储在变量中并测试该变量。您的源XML中也有错误,您需要/ team。

<xsl:template match="/">
    <html>
        <body>
            <table>
                <tr>
                    <th>User</th>
                    <th>Task Count</th>
                </tr>
                <xsl:for-each select="Activity/team/member">
                    <xsl:variable name="assignto">
                        <xsl:value-of select="."/>
                    </xsl:variable>
                    <tr>
                        <td><xsl:value-of select="node()" /></td>
                        <td><xsl:value-of select="count(/Activity/item[assignto=$assignto])" /></td>
                    </tr>
                </xsl:for-each>
            </table>
        </body>
    </html>
</xsl:template>

输出是:

<html>
<body>
  <table>
     <tr>
        <th>User</th>
        <th>Task Count</th>
     </tr>
     <tr>
        <td>User1</td>
        <td>2</td>
     </tr>
     <tr>
        <td>User2</td>
        <td>1</td>
     </tr>
  </table>
</body>
</html>

答案 1 :(得分:0)

只需将对'user1'的引用替换为对XPath地址开头的当前节点的引用,即使用current()函数完成:

t:\ftemp>type activity.xml 
<Activity>
     <item>
        <task>XXX</task>
        <assignto>User1</assignto>
     </item>
     <item>
        <task>YYY</task>
        <assignto>User2</assignto>
     </item>
     <item>
        <task>ZZZ</task>
        <assignto>User1</assignto>
     </item>
     <team>
        <member>User1</member>
        <member>User2</member>
     </team>
</Activity>

t:\ftemp>call xslt activity.xml activity.xsl 
<html>
   <body>
      <table>
         <tr>
            <th>User</th>
            <th>Task Count</th>
         </tr>
         <tr>
            <td>User1</td>
            <td>2</td>
         </tr>
         <tr>
            <td>User2</td>
            <td>1</td>
         </tr>
      </table>
   </body>
</html>
t:\ftemp>type activity.xsl 
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
    <table>
       <tr>
           <th>User</th>
           <th>Task Count</th>
       </tr>
       <xsl:for-each select="Activity/team/member">
          <tr>
               <td><xsl:value-of select="node()" /></td>
               <td><xsl:value-of select="count(/Activity/item[assignto=current()])" /></td>
          </tr>
       </xsl:for-each>
    </table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

t:\ftemp>rem Done! 

答案 2 :(得分:0)

如果要根据当前成员进行过滤,可以使用“current()”函数:

<xsl:value-of select="count(/Activity/item[assignto=current()])" />

但是,您可以从这里使用密钥中受益,以提高计数效率。首先像这样定义你的密钥:

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

然后你可以像这样写下你的计数:

 <xsl:value-of select="count(key('item', .))" />

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:key name="item" match="item" use="assignto" />
    <xsl:template match="/">
    <html>
    <body>
        <table>
           <tr>
               <th>User</th>
               <th>Task Count</th>
           </tr>
           <xsl:for-each select="Activity/team/member">
              <tr>
                   <td><xsl:value-of select="node()" /></td>
                   <td><xsl:value-of select="count(key('item', .))" /></td>
              </tr>
           </xsl:for-each>
        </table>
    </body>
    </html>
    </xsl:template>
</xsl:stylesheet>