计算XML文档中特定节点的频率

计算XML文档中特定节点的频率,xml,xslt,xpath,Xml,Xslt,Xpath,这可能已经被覆盖过了,但在谷歌搜索了很多之后,我似乎找不到任何例子。基本上,我是想得到一本书被借出的次数。下面给出了我的XML树,以及XSL和结果输出 <?xml-stylesheet type="text/xsl" href="LoanStyler.xsl"?> <loans> <loan id="0001"> <summary> <user>AAA</user> <dat

这可能已经被覆盖过了,但在谷歌搜索了很多之后,我似乎找不到任何例子。基本上,我是想得到一本书被借出的次数。下面给出了我的XML树,以及XSL和结果输出

    <?xml-stylesheet type="text/xsl" href="LoanStyler.xsl"?>
<loans>
  <loan id="0001">
    <summary>
      <user>AAA</user>
      <dateOut>2011-01-01</dateOut>
      <dateDue>2011-01-14</dateDue>
    </summary>
    <details>
      <books>
        <name>Book7</name>
        <name>Book4</name>
      </books>
    </details>
  </loan>
  <loan id="0002">
    <summary>
      <user>BBB</user>
      <dateOut>2011-01-10</dateOut>
      <dateDue>2011-01-24</dateDue>
    </summary>
    <details>
      <books>
        <name>Book1</name>
        <name>Book2</name>
        <name>Book4</name>
        <name>Book6</name>
      </books>
    </details>
  </loan>
  <loan id="0003">
    <summary>
      <user>CCC</user>
      <dateOut>2011-01-14</dateOut>
      <dateDue>2011-01-28</dateDue>
    </summary>
    <details>
      <books>
        <name>Book1</name>
        <name>Book3</name>
        <name>Book4</name>
        <name>Book7</name>
        <name>Book8</name>
      </books>
    </details>
  </loan>
  <loan id="0004">
    <summary>
      <user>DDD</user>
      <dateOut>2011-02-01</dateOut>
      <dateDue>2011-02-14</dateDue>
    </summary>
    <details>
      <books>
        <name>Book1</name>
        <name>Book2</name>
        <name>Book4</name>
      </books>
    </details>
  </loan>
</loans>

    <?xml version="1.0" encoding="ISO-8859-1"?>

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

<xsl:key 
    name="books-by-name" 
    match="//loans/loan/details/books" 
    use="name" 
  />


<xsl:template match="/">
  <html>
  <body>
    <h1>Loan Records Log</h1>
    <table Border="1">
        <tr>
            <th>Loan ID</th>
            <th>User</th>
            <th>Date Out</th>
            <th>Date Due</th>
        </tr>
        <xsl:for-each select="//loans/loan">
            <tr>
                <td><xsl:value-of select="@id"/></td>
                <td><xsl:value-of select="summary/user"/></td>
                <td><xsl:value-of select="summary/dateOut"/></td>
                <td><xsl:value-of select="summary/dateDue"/></td>
            </tr>
        </xsl:for-each>
    </table>

    <table Border="1">
        <tr>
            <th>Book name</th>
            <th>Count</th>
        </tr>

        <xsl:for-each select="books[count(. | key('books-by-name', name)[1]) = 1]">
            <tr>
                <td><xsl:value-of select="name" /></td>
                <td><xsl:value-of select="count(key('books-by-name', name))" /></td>
            </tr>
        </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

Loan Records Log
Loan ID User    Date Out    Date Due
0001    AAA 2011-01-01  2011-01-14
0002    BBB 2011-01-10  2011-01-24
0003    CCC 2011-01-14  2011-01-28
0004    DDD 2011-02-01  2011-02-14
Book name   Count

AAA
2011-01-01
2011-01-14
第七册
第四册
BBB
2011-01-10
2011-01-24
第一册
第二册
第四册
第六册
CCC
2011-01-14
2011-01-28
第一册
第三册
第四册
第七册
第八册
DDD
2011-02-01
2011-02-14
第一册
第二册
第四册
贷款记录日志
贷款ID
使用者
注明日期
到期日
书名
计数
贷款记录日志
贷款ID用户日期到期日期
0001 AAA 2011-01-01 2011-01-14
0002桶2011-01-10 2011-01-24
0003 CCC 2011-01-14 2011-01-28
0004 DDD 2011-02-01 2011-02-14
书名计数

正如你所看到的,明钦教的分组尝试似乎没有奏效。有人能解释一下我做错了什么,因为我能找到的唯一的例子似乎没有帮助。

问题就在这里

   <xsl:for-each select="books
                 [count(. | key('books-by-name', name)[1]) = 1]"> 
   <xsl:for-each select="loans/loan/details/books
                 [count(. | key('books-by-name', name)[1]) = 1]"> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key      name="books-by-name"
    match="books/name"      use="."    />
    <xsl:template match="/">
        <html>
            <body>
                <h1>Loan Records Log</h1>
                <table Border="1">
                    <tr>
                        <th>Loan ID</th>
                        <th>User</th>
                        <th>Date Out</th>
                        <th>Date Due</th>
                    </tr>
                    <xsl:for-each select="//loans/loan">
                        <tr>
                            <td>
                                <xsl:value-of select="@id"/>
                            </td>
                            <td>
                                <xsl:value-of select="summary/user"/>
                            </td>
                            <td>
                                <xsl:value-of select="summary/dateOut"/>
                            </td>
                            <td>
                                <xsl:value-of select="summary/dateDue"/>
                            </td>
                        </tr>
                    </xsl:for-each>
                </table>
                <table Border="1">
                    <tr>
                        <th>Book name</th>
                        <th>Count</th>
                    </tr>
                    <xsl:for-each select="loans/loan/details/books/name
                            [count(. | key('books-by-name', name)[1]) = 1]">
                        <tr>
                            <td>
                                <xsl:value-of select="." />
                            </td>
                            <td>
                                <xsl:value-of select="count(key('books-by-name',.))" />
                            </td>
                        </tr>
                    </xsl:for-each>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:

<loans>
    <loan id="0001">
        <summary>
            <user>AAA</user>
            <dateOut>2011-01-01</dateOut>
            <dateDue>2011-01-14</dateDue>
        </summary>
        <details>
            <books>
                <name>Book7</name>
                <name>Book4</name>
            </books>
        </details>
    </loan>
    <loan id="0002">
        <summary>
            <user>BBB</user>
            <dateOut>2011-01-10</dateOut>
            <dateDue>2011-01-24</dateDue>
        </summary>
        <details>
            <books>
                <name>Book1</name>
                <name>Book2</name>
                <name>Book4</name>
                <name>Book6</name>
            </books>
        </details>
    </loan>
    <loan id="0003">
        <summary>
            <user>CCC</user>
            <dateOut>2011-01-14</dateOut>
            <dateDue>2011-01-28</dateDue>
        </summary>
        <details>
            <books>
                <name>Book1</name>
                <name>Book3</name>
                <name>Book4</name>
                <name>Book7</name>
                <name>Book8</name>
            </books>
        </details>
    </loan>
    <loan id="0004">
        <summary>
            <user>DDD</user>
            <dateOut>2011-02-01</dateOut>
            <dateDue>2011-02-14</dateDue>
        </summary>
        <details>
            <books>
                <name>Book1</name>
                <name>Book2</name>
                <name>Book4</name>
            </books>
        </details>
    </loan>
</loans>
<html>
   <body>
      <h1>Loan Records Log</h1>
      <table Border="1">
         <tr>
            <th>Loan ID</th>
            <th>User</th>
            <th>Date Out</th>
            <th>Date Due</th>
         </tr>
         <tr>
            <td>0001</td>
            <td>AAA</td>
            <td>2011-01-01</td>
            <td>2011-01-14</td>
         </tr>
         <tr>
            <td>0002</td>
            <td>BBB</td>
            <td>2011-01-10</td>
            <td>2011-01-24</td>
         </tr>
         <tr>
            <td>0003</td>
            <td>CCC</td>
            <td>2011-01-14</td>
            <td>2011-01-28</td>
         </tr>
         <tr>
            <td>0004</td>
            <td>DDD</td>
            <td>2011-02-01</td>
            <td>2011-02-14</td>
         </tr>
      </table>
      <table Border="1">
         <tr>
            <th>Book name</th>
            <th>Count</th>
         </tr>
         <tr>
            <td>Book7</td>
            <td>2</td>
         </tr>
         <tr>
            <td>Book4</td>
            <td>4</td>
         </tr>
         <tr>
            <td>Book1</td>
            <td>3</td>
         </tr>
         <tr>
            <td>Book2</td>
            <td>2</td>
         </tr>
         <tr>
            <td>Book4</td>
            <td>4</td>
         </tr>
         <tr>
            <td>Book6</td>
            <td>1</td>
         </tr>
         <tr>
            <td>Book1</td>
            <td>3</td>
         </tr>
         <tr>
            <td>Book3</td>
            <td>1</td>
         </tr>
         <tr>
            <td>Book4</td>
            <td>4</td>
         </tr>
         <tr>
            <td>Book7</td>
            <td>2</td>
         </tr>
         <tr>
            <td>Book8</td>
            <td>1</td>
         </tr>
         <tr>
            <td>Book1</td>
            <td>3</td>
         </tr>
         <tr>
            <td>Book2</td>
            <td>2</td>
         </tr>
         <tr>
            <td>Book4</td>
            <td>4</td>
         </tr>
      </table>
   </body>
</html>

AAA
2011-01-01
2011-01-14
第七册
第四册
BBB
2011-01-10
2011-01-24
第一册
第二册
第四册
第六册
CCC
2011-01-14
2011-01-28
第一册
第三册
第四册
第七册
第八册
DDD
2011-02-01
2011-02-14
第一册
第二册
第四册
生成所需的正确结果:

<loans>
    <loan id="0001">
        <summary>
            <user>AAA</user>
            <dateOut>2011-01-01</dateOut>
            <dateDue>2011-01-14</dateDue>
        </summary>
        <details>
            <books>
                <name>Book7</name>
                <name>Book4</name>
            </books>
        </details>
    </loan>
    <loan id="0002">
        <summary>
            <user>BBB</user>
            <dateOut>2011-01-10</dateOut>
            <dateDue>2011-01-24</dateDue>
        </summary>
        <details>
            <books>
                <name>Book1</name>
                <name>Book2</name>
                <name>Book4</name>
                <name>Book6</name>
            </books>
        </details>
    </loan>
    <loan id="0003">
        <summary>
            <user>CCC</user>
            <dateOut>2011-01-14</dateOut>
            <dateDue>2011-01-28</dateDue>
        </summary>
        <details>
            <books>
                <name>Book1</name>
                <name>Book3</name>
                <name>Book4</name>
                <name>Book7</name>
                <name>Book8</name>
            </books>
        </details>
    </loan>
    <loan id="0004">
        <summary>
            <user>DDD</user>
            <dateOut>2011-02-01</dateOut>
            <dateDue>2011-02-14</dateDue>
        </summary>
        <details>
            <books>
                <name>Book1</name>
                <name>Book2</name>
                <name>Book4</name>
            </books>
        </details>
    </loan>
</loans>
<html>
   <body>
      <h1>Loan Records Log</h1>
      <table Border="1">
         <tr>
            <th>Loan ID</th>
            <th>User</th>
            <th>Date Out</th>
            <th>Date Due</th>
         </tr>
         <tr>
            <td>0001</td>
            <td>AAA</td>
            <td>2011-01-01</td>
            <td>2011-01-14</td>
         </tr>
         <tr>
            <td>0002</td>
            <td>BBB</td>
            <td>2011-01-10</td>
            <td>2011-01-24</td>
         </tr>
         <tr>
            <td>0003</td>
            <td>CCC</td>
            <td>2011-01-14</td>
            <td>2011-01-28</td>
         </tr>
         <tr>
            <td>0004</td>
            <td>DDD</td>
            <td>2011-02-01</td>
            <td>2011-02-14</td>
         </tr>
      </table>
      <table Border="1">
         <tr>
            <th>Book name</th>
            <th>Count</th>
         </tr>
         <tr>
            <td>Book7</td>
            <td>2</td>
         </tr>
         <tr>
            <td>Book4</td>
            <td>4</td>
         </tr>
         <tr>
            <td>Book1</td>
            <td>3</td>
         </tr>
         <tr>
            <td>Book2</td>
            <td>2</td>
         </tr>
         <tr>
            <td>Book4</td>
            <td>4</td>
         </tr>
         <tr>
            <td>Book6</td>
            <td>1</td>
         </tr>
         <tr>
            <td>Book1</td>
            <td>3</td>
         </tr>
         <tr>
            <td>Book3</td>
            <td>1</td>
         </tr>
         <tr>
            <td>Book4</td>
            <td>4</td>
         </tr>
         <tr>
            <td>Book7</td>
            <td>2</td>
         </tr>
         <tr>
            <td>Book8</td>
            <td>1</td>
         </tr>
         <tr>
            <td>Book1</td>
            <td>3</td>
         </tr>
         <tr>
            <td>Book2</td>
            <td>2</td>
         </tr>
         <tr>
            <td>Book4</td>
            <td>4</td>
         </tr>
      </table>
   </body>
</html>

贷款记录日志
贷款ID
使用者
注明日期
到期日
0001
AAA
2011-01-01
2011-01-14
0002
BBB
2011-01-10
2011-01-24
0003
CCC
2011-01-14
2011-01-28
0004
DDD
2011-02-01
2011-02-14
书名
计数
第七册
2.
第四册
4.
第一册
3.
第二册
2.
第四册
4.
第六册
1.
第一册
3.
第三册
1.
第四册
4.
第七册
2.
第八册
1.
第一册
3.
第二册
2.
第四册
4.

问得好,+1。请参阅我的答案,了解问题的解释和快速简单的解决方案。嗨,迪米特里,谢谢你的回复。但是,当按照建议将额外路径添加到select值中时,我只得到以下输出:Book name Count Book7 4,正如我尝试实现的那样:Book name Count Book7 2 Book4 Book1 3 Book2 Book3 Book3 1 Book8 1我认为for each会处理通过不同书籍的循环,第二次计数将返回每个不同的数字。很抱歉,前面的评论中缺少格式,但我想你能明白我的意思。@Ben:是的,你的解决方案中也有一个逻辑错误--我更新了我的答案,现在它显示了一个完全正确的解决方案。@Dimitre:谢谢,太棒了。我想我现在可以看出我错在哪里了。@Dimitre:+1以获得正确答案。我认为您应该添加对多值键问题的解释,因为许多人认为键是一对一的,而不是多对多的。