您好我想在XSLT中进行一些聚合。例如,我有以下xml文件。
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<reporting:root xmlns:reporting="testing">
<reporting:default0 reporting:type="Portfolio">
<reporting:window reporting:Id="1" reporting:level="0" reporting:name="TEST" reporting:parentId="-1">
<reporting:folio reporting:Id="2" reporting:criteria="0" reporting:level="1" reporting:name="topfolder1" reporting:parentId="1">
<reporting:folio reporting:Id="37" reporting:criteria="0" reporting:level="2" reporting:name="folder2" reporting:parentId="2">
<reporting:folio reporting:Id="38" reporting:criteria="0" reporting:level="3" reporting:name="folder3" reporting:parentId="37">
<reporting:folio reporting:Id="196" reporting:criteria="0" reporting:level="4" reporting:name="folder4" reporting:parentId="38">
<reporting:line reporting:Id="123456" reporting:level="5" reporting:name="element1" reporting:parentId="196" reporting:positionType="0">
<reporting:reference>element1</reporting:reference>
<reporting:number>625</reporting:number>
</reporting:line>
<reporting:line reporting:Id="223456" reporting:level="5" reporting:name="element2" reporting:parentId="196" reporting:positionType="7">
<reporting:reference>element2</reporting:reference>
<reporting:number>475</reporting:number>
</reporting:line>
<reporting:folio reporting:Id="209" reporting:criteria="0" reporting:level="5" reporting:name="delta" reporting:parentId="196">
<reporting:line reporting:Id="223456" reporting:level="6" reporting:name="element2" reporting:parentId="209" reporting:positionType="0">
<reporting:reference>element2</reporting:reference>
<reporting:number>190</reporting:number>
</reporting:line>
</reporting:folio>
</reporting:folio>
</reporting:folio>
</reporting:folio>
</reporting:folio>
<reporting:folio reporting:Id="4" reporting:criteria="0" reporting:level="1" reporting:name="topfolder2" reporting:parentId="1">
<reporting:folio reporting:Id="39" reporting:criteria="0" reporting:level="2" reporting:name="folder24" reporting:parentId="4">
<reporting:folio reporting:Id="40" reporting:criteria="0" reporting:level="3" reporting:name="folder34" reporting:parentId="39">
<reporting:folio reporting:Id="296" reporting:criteria="0" reporting:level="4" reporting:name="folder44" reporting:parentId="40">
<reporting:line reporting:Id="123456" reporting:level="5" reporting:name="element3" reporting:parentId="296" reporting:positionType="0">
<reporting:reference>element3</reporting:reference>
<reporting:number>65525</reporting:number>
</reporting:line>
<reporting:folio reporting:Id="309" reporting:criteria="0" reporting:level="5" reporting:name="delta" reporting:parentId="296">
<reporting:line reporting:Id="2234567" reporting:level="6" reporting:name="element4" reporting:parentId="309" reporting:positionType="0">
<reporting:reference>element4</reporting:reference>
<reporting:number>490</reporting:number>
</reporting:line>
</reporting:folio>
</reporting:folio>
</reporting:folio>
</reporting:folio>
</reporting:folio>
</reporting:window>
</reporting:default0>
</reporting:root>
然后我想在'2级'做一些聚合。即应该返回'reporting:line'中的任何内容,并且它的级别1和级别2的父级'报告:folio'也应该返回。同样对于level2文件夹的anysubfolder下的相同元素应该聚合为一个。并且还计算了总和(数字)。
也是没有。在有报告之前,子作品集可以是200:行标记。
所以对于这个xml我希望结果是:
topfolder,folder2,element1,625
topfolder,folder2,element2,665
topfolder2,folder24,element3,65525
topfolder2,folder24,element4,490
希望我能正确解释。真的很感谢你的帮助。
答案 0 :(得分:2)
在这种情况下,您需要先进行分组,然后再进行聚合。您需要按作品集级别1,作品集级别2和元素名称对元素进行分组。为此,您通常使用Muenchian分组方法。
首先,您定义一个 xsl:key ,可用于将所有匹配的元素组合在一起
<xsl:key name="lines" match="reporting:line" use="
concat(
concat(
concat(ancestor::reporting:folio[@reporting:level='1']/@reporting:name, ','),
concat(ancestor::reporting:folio[@reporting:level='2']/@reporting:name, ',')
),
@reporting:name
)" />
接下来,您需要选择每个组中的第一个匹配元素。
<xsl:apply-templates select="//reporting:line
[generate-id() =
generate-id(key('lines', ...concatenated key... )[1])]" />
然后,这是一个“简单”的案例,总结了与查找键匹配的所有元素
<xsl:value-of select="sum(key('lines', $keyName)/reporting:number)" />
完全放弃
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:reporting="testing">
<xsl:output method="text" indent="yes"/>
<xsl:key name="lines" match="reporting:line" use="concat(concat(concat(ancestor::reporting:folio[@reporting:level='1']/@reporting:name, ','), concat(ancestor::reporting:folio[@reporting:level='2']/@reporting:name, ',')), @reporting:name)" />
<xsl:template match="/">
<xsl:apply-templates select="//reporting:line[generate-id() = generate-id(key('lines', concat(concat(concat(ancestor::reporting:folio[@reporting:level='1']/@reporting:name, ','), concat(ancestor::reporting:folio[@reporting:level='2']/@reporting:name, ',')), @reporting:name))[1])]" />
</xsl:template>
<xsl:template match="reporting:line">
<xsl:variable name="keyName" select="concat(concat(concat(ancestor::reporting:folio[@reporting:level='1']/@reporting:name, ','), concat(ancestor::reporting:folio[@reporting:level='2']/@reporting:name, ',')), @reporting:name)" />
<xsl:value-of select="$keyName" />
<xsl:text>,</xsl:text>
<xsl:value-of select="sum(key('lines', $keyName)/reporting:number)" />
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
当应用于您的示例XML时,输出如下:
topfolder1,folder2,element1,625
topfolder1,folder2,element2,665
topfolder2,folder24,element3,65525
topfolder2,folder24,element4,490