避免重置位置xslt



对于每一组,我都必须按照相同数量的艺术家进行分组。在输出中,我必须显示每组的位置(输出:1、2、3(,但当进入组的第二个循环时,位置重置,当前输出为(错误输出:1,2,1(。

<xsl:for-each select="group"> <xsl:for-each-group select="artist" group-by="number"> <position> <xsl:value of select="position()"/> </position> <counter> <xsl:value of select="count(number)"/></counter> </xsl:for-each-group> </xsl:for-each>

or 

<xsl:for-each select="group"> <xsl:for-each-group select="artist" group-by="number"> <position> <xsl:value of select="position()"/> </position> <counter> <xsl:value of select="count(number)"/></counter> </xsl:for-each-group> </xsl:for-each>

<?xml version="1.0" encoding="UTF-8"?>
<group>
<artist>
<number>1</number>
</artist>
<artist>
<number>1</number>
</artist>
<artist>
<number>2</number>
</artist>
<artist>
<number>2</number>
</artist>
</group>
<group>
<artist>
<number>5</number>
</artist>
<artist>
<number>5</number>
</artist>
</group>

根据需要的输出,听起来您不需要也不需要外部for-each,而是直接想用例如对所有artist进行分组

<xsl:for-each-group select="group/artist" group-by="number">

对于您的样本数据,这将给出三个组,内部<xsl:value of select="position()"/>将以这种方式输出序列1、2、3。

使用XSLT2或3,您可以临时存储不同的组,例如在XSLT3中作为映射序列:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
expand-text="yes"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-skip"/>
<xsl:output method="xml" indent="yes" />
<xsl:template match="root">
<xsl:copy>
<xsl:variable name="groups" as="map(*)*">
<xsl:apply-templates/>
</xsl:variable>
<xsl:apply-templates select="$groups"/>
</xsl:copy>
</xsl:template>

<xsl:template match="group">
<xsl:for-each-group select="artist" group-by="number">
<xsl:sequence select="map:entry(current-grouping-key(), current-group())"/>
</xsl:for-each-group>
</xsl:template>

<xsl:template match=".[. instance of map(*)]">
<group position="{position()}" number-count="{count(?*/number)}"/>
</xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/6qjt5Re

这里有一个例子,展示了如何在保持所有父组计数的同时,按顺序对所有子组进行编号:

XML

<input>
<group>
<item>
<category>a</category>
</item>
<item>
<category>a</category>
</item>
<item>
<category>a</category>
</item>
<item>
<category>b</category>
</item>
<item>
<category>b</category>
</item>
</group>
<group>
<item>
<category>a</category>
</item>
<item>
<category>a</category>
</item>
</group>
<group>
<item>
<category>a</category>
</item>
<item>
<category>a</category>
</item>
<item>
<category>b</category>
</item>
</group>
</input>

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/input">
<xsl:variable name="categories" select="distinct-values(group/item/concat(category, '|', generate-id(..)))" />
<output>
<xsl:for-each select="group"> 
<group group-num="{position()}" count-categories="{count(distinct-values(item/category))}" count-items="{count(item)}">
<xsl:for-each-group select="item" group-by="category">
<category category-num="{index-of($categories, concat(category, '|', generate-id(..)))}" count-items="{count(current-group())}">
<xsl:value-of select="category"/> 
</category>
</xsl:for-each-group>
</group>
</xsl:for-each> 
</output>
</xsl:template>
</xsl:stylesheet>

结果

<?xml version="1.0" encoding="UTF-8"?>
<output>
<group group-num="1" count-categories="2" count-items="5">
<category category-num="1" count-items="3">a</category>
<category category-num="2" count-items="2">b</category>
</group>
<group group-num="2" count-categories="1" count-items="2">
<category category-num="3" count-items="2">a</category>
</group>
<group group-num="3" count-categories="2" count-items="3">
<category category-num="4" count-items="2">a</category>
<category category-num="5" count-items="1">b</category>
</group>
</output>

如果每个组都有自己不同的类别,那么这可以进一步简化。

最新更新