将两个 xml 文件分组,如 sql group-by [2]
Posted
技术标签:
【中文标题】将两个 xml 文件分组,如 sql group-by [2]【英文标题】:Groups two xml files like a sql group-by [2] 【发布时间】:2012-01-11 10:47:40 【问题描述】:这是我的问题的演变: Groups two xml files like a sql group-by 给出的示例和 Dimitre 解决方案正在计算不同的 isbn 值。 现在将库 xml 修改为 mylibrary.xml:
<library>
<book id="1" isbn="1"/>
<book id="2" isbn="1"/>
<book id="3" isbn="2"/>
<book id="4" isbn="4"/>
<book id="5" isbn="5"/>
<book id="6" isbn="4"/>
<book id="7" isbn="4"/>
</library>
还有这个可以使用的: bookreference.xml:
<reference>
<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>
</reference>
我想使用 xslt 1-0 获取我在 mylibrary 中“即使有些具有相同的 isbn”、groupby 类别的书的数量。
想要的输出:
SF : 3 book(s)
Comedy : 4 book(s)
我的 xslt 建议在这里:Groups two xml files like a sql group-by 工作正常,但当然使用“for-each”循环和扩展函数。 当然有更好的解决方案。
【问题讨论】:
【参考方案1】:又是一个非常好的问题! (+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="kBookByIsbn" match="book"
use="@isbn"/>
<xsl:variable name="vDoc" select="/"/>
<xsl:variable name="vRef" select=
"document('file:///c:/temp/delete/reference.xml')"/>
<xsl:variable name="vMyIsbns" select="/*/*/@isbn"/>
<xsl:variable name="vResult">
<xsl:apply-templates select="$vRef/*"/>
</xsl:variable>
<xsl:template match="/">
<xsl:copy-of select="$vResult"/>
</xsl:template>
<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:for-each select="$vDoc">
<xsl:value-of select="count(key('kBookByIsbn',$vBooksinCat/@isbn))"/>
</xsl:for-each>
<xsl:text> book(s)
</xsl:text>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
应用于 mylibrary.xml 文件中所提供的 XML 文档时:
<library>
<book id="1" isbn="1"/>
<book id="2" isbn="1"/>
<book id="3" isbn="2"/>
<book id="4" isbn="4"/>
<book id="5" isbn="5"/>
<book id="6" isbn="4"/>
<book id="7" isbn="4"/>
</library>
并在 C:\temp\delete\reference.xml 中提供此 XML 文档:
<reference>
<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>
</reference>
产生想要的、正确的输出:
SF : 3 book(s)
Comedy : 4 book(s)
【讨论】:
看到你总是领先一步:P 虽然由于某种原因,当我测试解决方案时,2 个独特类别的模板匹配似乎不起作用(vs2008),直到我移动它,你会看到如果你看看答案之间的差异,我的意思是什么! 又是一个很好的答案,非常感谢,我就像一个学生在问题和我的坏处花费数小时:永远找不到解决方案,当你在 ... 5 分钟内完成时? 我还没有足够的声誉 ( @Seb:不客气。不用担心要花很多时间——这就是你逐渐减少花时间的方法:) @Seb: Re: [代码修改为在书籍数量 = 0 时不显示类别] ==> 只需为类别添加另一个变量并稍微重新排列代码。【参考方案2】:修改后的 Dimitri 版本适用于此
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kBookByCat" match="book" use="category"/>
<xsl:variable name="vRef" select="document('file:///c:/temp/delete/reference.xml')"/>
<xsl:variable name="meh" select="*"/>
<xsl:template match="/">
<xsl:apply-templates select="$vRef/reference/book[generate-id()=generate-id(key('kBookByCat', category)[1])]" />
</xsl:template>
<xsl:template match="book">
<xsl:variable name="cat" select="category"/>
<xsl:value-of select="category"/> : <xsl:text/>
<xsl:variable name="isbns" select="$vRef/reference/book[category=$cat]/@isbn"/>
<xsl:value-of select="count($meh/book[@isbn=$isbns])"/>
<xsl:text> book(s)
</xsl:text>
</xsl:template>
【讨论】:
【参考方案3】:除了伟大的 dimitri 响应外,我建议不要打印在 mylibrary 中设置为 0 的图书类别:
<xsl:variable name="catname" select="category"/>
<xsl:for-each select="$vDoc">
<xsl:variable name="cnt" select="count(key('kBookByIsbn',$vBooksinCat/@isbn))"/>
<xsl:if test="$cnt > 0">
<xsl:value-of select="$catname"/> :
<xsl:text/>
<xsl:value-of select="$cnt"/>
<xsl:text> book(s)
</xsl:text>
</xsl:if>
</xsl:for-each>
【讨论】:
以上是关于将两个 xml 文件分组,如 sql group-by [2]的主要内容,如果未能解决你的问题,请参考以下文章
SQL语句中,如果有group by 和order by两个语句,是先分组还是先排序?