想使用手动XSLT根据相似的包ID对请求进行分组
这是包含plan_id
且需要分组的输入xml
<subscriptions>
<package>
<package_plan>
<plan_id>1111</plan_id>
<plan_name>economy1</plan_name>
</package_plan>
<rate_channel>
<rateid>1F1</rateid>
<currency>USD</currency>
<package_duration>monthly</package_duration>
<price>3</price>
</rate_channel>
</package>
<package>
<package_plan>
<plan_id>1111</plan_id>
<plan_name>economy1</plan_name>
</package_plan>
<rate_channel>
<rateid>1F2</rateid>
<currency>USD</currency>
<package_duration>quaterly</package_duration>
<price>11</price>
</rate_channel>
</package>
<package>
<package_plan>
<plan_id>2222</plan_id>
<plan_name>economy2</plan_name>
</package_plan>
<rate_channel>
<rateid>1F3</rateid>
<currency>INR</currency>
<package_duration>monthly</package_duration>
<price>250</price>
</rate_channel>
</package>
</subscriptions>
寻找输出为:
<subscriptions>
<package>
<plan_id>1111</plan_id>
<plan_name>economy1</plan_name>
<channels>
<rate_channel>
<rateid>1F1</rateid>
<currency>USD</currency>
<package_duration>monthly</package_duration>
<price>3</price>
</rate_channel>
<rate_channel>
<rateid>1F2</rateid>
<currency>USD</currency>
<package_duration>quaterly</package_duration>
<price>11</price>
</rate_channel>
</channels>
</package>
<package>
<plan_id>2222</plan_id>
<plan_name>economy2</plan_name>
<channels>
<rate_channel>
<rateid>1F3</rateid>
<currency>INR</currency>
<package_duration>monthly</package_duration>
<price>250</price>
</rate_channel>
</channels>
</package>
</subscriptions>
我一直在搜索并阅读其他帖子,但我认为它们并不能完全覆盖我想做的事情 预先感谢...
答案 0 :(得分:2)
下面是XSLT 1.0和XSLT 2.0解决方案。两种解决方案都使用@Tim C在评论中正确指出的方法。
XSLT 1.0
对于XSLT 1.0,使用muenchian grouping。需要定义<xsl:key>
才能对元素进行分组。在这种情况下,<plan_id>
是进行分组的键。
<xsl:key name="plan" match="package" use="package_plan/plan_id" />
package
元素将进行相应匹配,并将分组的数据复制到输出中。
<xsl:template match="package[generate-id() = generate-id(key('plan', package_plan/plan_id)[1])]">
<xsl:copy>
<xsl:variable name="varPlan" select="key('plan', package_plan/plan_id)" />
<xsl:apply-templates select="$varPlan[1]/package_plan/plan_id" />
<xsl:apply-templates select="$varPlan[1]/package_plan/plan_name" />
<channels>
<xsl:for-each select="$varPlan">
<xsl:apply-templates select="rate_channel" />
</xsl:for-each>
</channels>
</xsl:copy>
</xsl:template>
其余<package>
个元素被删除。
<xsl:template match="package" />
XSLT 2.0
在XSLT 2.0中,<xsl-for-each-group>
功能特别适用于元素分组。在这种情况下,使用此功能和current-group()
函数可以实现分组。
<xsl:template match="subscriptions">
<xsl:copy>
<xsl:for-each-group select="package" group-by="package_plan/plan_id">
<package>
<xsl:apply-templates select="current-group()[1]/package_plan/plan_id" />
<xsl:apply-templates select="current-group()[1]/package_plan/plan_name" />
<channels>
<xsl:for-each select="current-group()">
<xsl:apply-templates select="rate_channel" />
</xsl:for-each>
</channels>
</package>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
在以上两种情况下,都应使用identity transform
模板将数据原样复制到输出中。
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>