【发布时间】:2017-11-01 10:43:19
【问题描述】:
我试图弄清楚如何在需要分组(具有任意数量的组)并对组求和的场景中使用 XSLT Streaming(以减少内存使用)。到目前为止,我还没有找到任何例子。这是一个 XML 示例
<?xml version='1.0' encoding='UTF-8'?>
<Data>
<Entry>
<Genre>Fantasy</Genre>
<Condition>New</Condition>
<Format>Hardback</Format>
<Title>Birds</Title>
<Count>3</Count>
</Entry>
<Entry>
<Genre>Fantasy</Genre>
<Condition>New</Condition>
<Format>Hardback</Format>
<Title>Cats</Title>
<Count>2</Count>
</Entry>
<Entry>
<Genre>Non-Fiction</Genre>
<Condition>New</Condition>
<Format>Paperback</Format>
<Title>Dogs</Title>
<Count>4</Count>
</Entry>
</Data>
在 XSLT 2.0 中,我会使用它来按流派、条件和格式分组,并对计数求和。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes" />
<xsl:template match="/">
<xsl:call-template name="body"/>
</xsl:template>
<xsl:template name="body">
<xsl:for-each-group select="Data/Entry" group-by="concat(Genre,Condition,Format)">
<xsl:value-of select="Genre"/>
<xsl:value-of select="Condition"/>
<xsl:value-of select="Format"/>
<xsl:value-of select="sum(current-group()/Count)"/>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
对于输出,我会得到两行,Fantasy、New、Hardback 的总和为 5,Non-Fiction、New、Paperback 的总和为 4。
显然这不适用于流式传输,因为总和会访问整个组。我想我需要遍历文档两次。我第一次可以构建组图(如果尚不存在,则创建一个新组)。第二次 问题是我还需要每个组的累加器,其规则与组匹配,看来你不能创建动态累加器。
有没有办法即时创建累加器?是否有另一种/更简单的方法来使用流式传输?
【问题讨论】:
-
一些想法:在 XSLT 3.0 中,我不会连接要分组的元素,而是使用
xsl:for-each-group select="Data/Entry" group-by="Genre,Condition,Format" composite="yes"。然而,对于流式分组,鉴于您想将group-by与子元素一起使用,您可以做的就是<xsl:for-each-groups select="copy-of(Data/Entry)" group-by="Genre,Condition,Format" composite="yes",否则如果不使用copy-of,您根本无法在group-by中选择子元素。跨度>
标签: xslt xslt-grouping xslt-3.0