在 group-by 中使用具有条件的 for-each-group
Using for-each-group with having a condition in group-by
我想使用 for-each-group
按 id
对项目进行分组,并且仅当它们位于不同的来源时才进行分组,如果来源相同,即使它具有相同的 ID 也不要分组
<items>
<item id="123" source="loc1">
<price>12</price>
<description>test</description>
</item>
<item id="123" source="loc2">
<price>122</price>
<description>test</description>
</item>
<item id="234" source="loc1">
<price>566</price>
<description>test</description>
</item>
<item id="456" source="loc2">
<price>222</price>
<description>desc</description>
</item>
<item id="456" source="loc2">
<price>312</price>
<description>desc</description>
</item>
<item id="768" source="loc1">
<price>212</price>
<description>desc</description>
</item>
<item id="768" source="loc2">
<price>934</price>
<description>desc</description>
</item>
</items>
输出是这样的
<items>
<group>
<item id="123" source="loc1">
<price>12</price>
<description>test</description>
</item>
<item id="123" source="loc2">
<price>122</price>
<description>test</description>
</item>
</group>
<group>
<item id="234" source="loc1">
<price>566</price>
<description>test</description>
</item>
</group>
<group>
<item id="456" source="loc2">
<price>222</price>
<description>desc</description>
</item>
</group>
<group>
<item id="456" source="loc2">
<price>222</price>
<description>desc</description>
</item>
</group>
<group>
<item id="768" source="loc1">
<price>212</price>
<description>desc</description>
</item>
<item id="768" source="loc2">
<price>934</price>
<description>desc</description>
</item>
</group>
</items>
更新
按id分组
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="items">
<xsl:copy>
<xsl:for-each-group select="item" group-by="@id">
<group>
<xsl:apply-templates select="current-group()"/>
</group>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我认为您的要求可以通过使用 group-by="@id"
来实现,然后在内部使用检查 count(distinct-values(current-group()/@source)) = count(current-group())
来决定是否将 current-group()
中的所有项目包装成一个 [=14] =] 元素包装器或是否包装它自己的每个项目:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="items">
<xsl:copy>
<xsl:for-each-group select="item" group-by="@id">
<xsl:choose>
<xsl:when test="count(distinct-values(current-group()/@source)) = count(current-group())">
<group>
<xsl:apply-templates select="current-group()"/>
</group>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="current-group()">
<group>
<xsl:apply-templates select="."/>
</group>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/pPqsHTR 上的在线示例,并不是我更正了您输入示例中的最后两个 item
元素,使其具有 source
属性,而不是它们具有的 name
在你的 post.
我想使用 for-each-group
按 id
对项目进行分组,并且仅当它们位于不同的来源时才进行分组,如果来源相同,即使它具有相同的 ID 也不要分组
<items>
<item id="123" source="loc1">
<price>12</price>
<description>test</description>
</item>
<item id="123" source="loc2">
<price>122</price>
<description>test</description>
</item>
<item id="234" source="loc1">
<price>566</price>
<description>test</description>
</item>
<item id="456" source="loc2">
<price>222</price>
<description>desc</description>
</item>
<item id="456" source="loc2">
<price>312</price>
<description>desc</description>
</item>
<item id="768" source="loc1">
<price>212</price>
<description>desc</description>
</item>
<item id="768" source="loc2">
<price>934</price>
<description>desc</description>
</item>
</items>
输出是这样的
<items>
<group>
<item id="123" source="loc1">
<price>12</price>
<description>test</description>
</item>
<item id="123" source="loc2">
<price>122</price>
<description>test</description>
</item>
</group>
<group>
<item id="234" source="loc1">
<price>566</price>
<description>test</description>
</item>
</group>
<group>
<item id="456" source="loc2">
<price>222</price>
<description>desc</description>
</item>
</group>
<group>
<item id="456" source="loc2">
<price>222</price>
<description>desc</description>
</item>
</group>
<group>
<item id="768" source="loc1">
<price>212</price>
<description>desc</description>
</item>
<item id="768" source="loc2">
<price>934</price>
<description>desc</description>
</item>
</group>
</items>
更新
按id分组
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="items">
<xsl:copy>
<xsl:for-each-group select="item" group-by="@id">
<group>
<xsl:apply-templates select="current-group()"/>
</group>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我认为您的要求可以通过使用 group-by="@id"
来实现,然后在内部使用检查 count(distinct-values(current-group()/@source)) = count(current-group())
来决定是否将 current-group()
中的所有项目包装成一个 [=14] =] 元素包装器或是否包装它自己的每个项目:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="items">
<xsl:copy>
<xsl:for-each-group select="item" group-by="@id">
<xsl:choose>
<xsl:when test="count(distinct-values(current-group()/@source)) = count(current-group())">
<group>
<xsl:apply-templates select="current-group()"/>
</group>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="current-group()">
<group>
<xsl:apply-templates select="."/>
</group>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/pPqsHTR 上的在线示例,并不是我更正了您输入示例中的最后两个 item
元素,使其具有 source
属性,而不是它们具有的 name
在你的 post.