我想做的是一个典型的分组,通常可以使用xsl:key完成,但它变得更加复杂,因为分组的数据在两个不同的文件中。怎样的过程?这是我想做的一个例子,我可以请求你的帮助吗?必须与xslt-1.0兼容。
bookreference.xml:
<t>
<book isbn="1">
<category>SF</category>
</book>
<book isbn="2">
<category>SF</category>
</book>
<book isbn="3">
<category>SF</category>
</book>
<book isbn="4">
<category>Comedy</category>
</book>
<book isbn="5">
<category>Comedy</category>
</book>
</t>
mylibrary.xml:
<t>
<book isbn="1">
<price>10</price>
</book>
<book isbn="2">
<price>10</price>
</book>
<book isbn="3">
<price>20</price>
</book>
<book isbn="4">
<price>5</price>
</book>
</t>
输出:
SF : 3 book(s) - Total : 40$
Comedy : 2 book(s) - Total : 5$
正如我在评论中已经建议的那样,您可以首先将两个文档合并为结果树片段,然后使用exsl:node-set获得一个节点集,然后可以在其上应用Muenchian分组:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="exsl"
version="1.0">
<xsl:param name="price-url" select="'test2011113002.xml'"/>
<xsl:variable name="doc2" select="document($price-url)"/>
<xsl:output method="text"/>
<xsl:variable name="rtf">
<xsl:apply-templates select="//book" mode="merge"/>
</xsl:variable>
<xsl:template match="book" mode="merge">
<xsl:copy>
<xsl:variable name="isbn" select="@isbn"/>
<xsl:copy-of select="@* | node()"/>
<xsl:for-each select="$doc2">
<xsl:copy-of select="key('k1', $isbn)/price"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:key name="k1" match="book" use="@isbn"/>
<xsl:key name="k2" match="book" use="category"/>
<xsl:template match="/">
<xsl:apply-templates select="exsl:node-set($rtf)/book[generate-id() = generate-id(key('k2', category)[1])]"/>
</xsl:template>
<xsl:template match="book">
<xsl:variable name="current-group" select="key('k2', category)"/>
<xsl:value-of select="concat($current-group/category, ': ', count($current-group), ' - Total : ', sum($current-group/price), ' ')"/>
</xsl:template>
</xsl:stylesheet>
好问题,+1。
不需要复杂的(多于必要的)分组或任何扩展函数 :
<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="kBookByCat" match="book"
use="category"/>
<xsl:key name="kPriceByIsbn" match="price"
use="../@isbn"/>
<xsl:variable name="vMyLib" select=
"document('file:///c:/temp/delete/mylibrary.xml')"/>
<xsl:template match=
"book[generate-id()
=
generate-id(key('kBookByCat', category)[1])
]
">
<xsl:variable name="vBooksinCat" select=
"key('kBookByCat', category)"/>
<xsl:value-of select="category"/> : <xsl:text/>
<xsl:value-of select="count($vBooksinCat)"/>
<xsl:text> book(s) - Total : $</xsl:text>
<xsl:for-each select="$vMyLib">
<xsl:value-of select="sum(key('kPriceByIsbn', $vBooksinCat/@isbn))"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
当对提供的两个数据片段(更正为格式良好的XML文档)中的第一个应用此转换时:
<t>
<book isbn="1">
<category>SF</category>
</book>
<book isbn="2">
<category>SF</category>
</book>
<book isbn="3">
<category>SF</category>
</book>
<book isbn="4">
<category>Comedy</category>
</book>
<book isbn="5">
<category>Comedy</category>
</book>
</t>
并将第二个数据片段(更正为格式良好的XML文档)保存为C:TempDeletemylibrary.xml
,
生成所需的正确结果:
SF : 3 book(s) - Total : $40
Comedy : 2 book(s) - Total : $5