XSLT 按变量分组
XSLT group by variable
输入:
<?xml version="1.0" encoding="UTF-8"?>
<output>
<input>
<!--details-->
</input>
<meta2>
<Comenzi>
<output_getquerydata>
<queries>
<query name="part1">
<parameters>
<!--details-->
</parameters>
<queryErrors>
<!--details-->
</queryErrors>
<queryResults>
<record id="1">
<column name="id_schedule">3</column>
<column name="VRIdTask">1319648</column>
<column name="MSSinergieOrderP"/>
<column name="MSSinergieTaskP"/>
<column name="VRPlanId">11310337</column>
<column name="TripLabel">189221</column>
<column name="MSSinergieOrderNP"/>
<column name="MSSinergieTaskNP"/>
</record>
<record id="2">
<column name="id_schedule">3</column>
<column name="VRIdTask">1319652</column>
<column name="MSSinergieOrderP">1320566</column>
<column name="MSSinergieTaskP">1319575</column>
<column name="VRPlanId">11310281</column>
<column name="TripLabel">189221</column>
<column name="MSSinergieOrderNP"/>
<column name="MSSinergieTaskNP"/>
</record>
<record id="3">
<column name="id_schedule">3</column>
<column name="VRIdTask">1319652</column>
<column name="MSSinergieOrderP">1320614</column>
<column name="MSSinergieTaskP">1319623</column>
<column name="VRPlanId">11310281</column>
<column name="TripLabel">189221</column>
<column name="MSSinergieOrderNP"/>
<column name="MSSinergieTaskNP"/>
</record>
<record id="4">
<column name="id_schedule">3</column>
<column name="VRIdTask">1319652</column>
<column name="MSSinergieOrderP">1320656</column>
<column name="MSSinergieTaskP">1319667</column>
<column name="VRPlanId">11310281</column>
<column name="TripLabel">189221</column>
<column name="MSSinergieOrderNP"/>
<column name="MSSinergieTaskNP"/>
</record>
</queryResults>
</query>
</queries>
</output_getquerydata>
</Comenzi>
</meta2>
</output>
XSL:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" />
<xsl:template name="task-attr">
<!--parameter to filter per VRPlanId-->
<xsl:param name="param.VRPlanId"/>
<xsl:variable name="var.mstp">
<xsl:for-each
select="/output/meta2/Comenzi/output_getquerydata/queries/query/queryResults/rec
ord[column[@name='VRPlanId'] = $param.VRPlanId]">
<!--preventing empty blocks and duplicates for MSTP-->
<xsl:if test="string-length(column[@name='MSSinergieTaskP']) >0
and not(preceding::record[column[@name='MSSinergieTaskP']/text() =
current()/column[@name='MSSinergieTaskP']/text()])">
<xsl:value-of select="concat(column[@name='MSSinergieTaskP'],
',')"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="var.msonpc">
<xsl:for-each
select="/output/meta2/Comenzi/output_getquerydata/queries/query/queryResults/re
cord[column[@name='VRPlanId'] = $param.VRPlanId]">
<!--preventing empty blocks and duplicates for MSONPC-->
<xsl:if test="string-length(column[@name='MSSinergieTaskNP']) >0
and not(preceding::record[column[@name='MSSinergieTaskNP']/text() =
current()/column[@name='MSSinergieTaskNP']/text()])">
<xsl:value-of select="concat(column[@name='MSSinergieTaskNP'],
',')"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<!--concat all non-duplicates MSTP and MSONPC without last delimiter-->
<xsl:value-of select="concat($var.mstp, substring($var.msonpc, 1, string-
length($var.msonpc)-1))"/>
</xsl:template>
<xsl:template match="/">
<output>
<xsl:for-each
select="/output/meta2/Comenzi/output_getquerydata/queries/query/queryResults/record">
<xsl:if test ="not(preceding::record[column[@name='VRPlanId']/text() =
current()/column[@name='VRPlanId']/text()])">
<xsl:variable name="task.id">
<xsl:call-template name="task-attr">
<!--as input parameter put non-duplicate VRPlanId-->
<xsl:with-param name="param.VRPlanId"
select="column[@name='VRPlanId']"/>
</xsl:call-template>
</xsl:variable>
<!--if all non-duplicates MSTP and MSONPC will be blank block
Cdo won't be created-->
<xsl:if test="string-length($task.id) >0">
<Cdo>
<parameters>
<task>
<xsl:attribute name="id">
<xsl:value-of select="$task.id"/>
</xsl:attribute>
</task>
<action>
<xsl:attribute name="id">
<xsl:value-of
select="column[@name='VRPlanId']"/>
</xsl:attribute>
</action>
</parameters>
</Cdo>
</xsl:if>
</xsl:if>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
大家好,
感谢您的帮助。
目标是检查我们构建标签的每个不同的 VRPlanID 值
如果标签的 id 部分中没有 null/empty,则将相应的 MSTP、MSONPC(不同)分组。
因此,我们在 VRPlanID 之后分组,然后从 MSTP/MSONPC 中的每条记录中获取不同的值。
如果它们是空的,那么只需构建一个虚拟/空 message/tag。
这有效,但我有 2 个问题:
- 我总是在最后一个 ID 后得到一个 ',' 逗号,我不明白为什么
- 我不再需要串联,但我想为每个 ID 设置一个标签任务
因此,所需的输出将是:
<output>
<Cdo>
<parameters>
<task id="1319575"/>
<task id="1319623"/>
<task id="1319667"/>
<action id="11310281"/>
</parameters>
</Cdo>
</output>
请记住,标签 MSInergieTaskP 和 MSInergieTaskNP 之间的任何组合都是可能的。所以一个可能是空的,另一个不是。或者只为一条记录留空,然后为下一条记录提供值。
我只是想为每个不同的 VRIdTask 获取任何组合的不同值。
我似乎无法让它工作。
请问有什么建议吗?
对于 XSLT 1.0 中的分组,最有效的解决方案是使用 muenchian grouping。
在这种情况下,您可以使用属性 @name='VRPlanId'
.
中的值创建一个 分组键
<xsl:key name="vrPlanId" match="record" use="column[@name='VRPlanId']" />
然后使用键对节点进行分组
<xsl:apply-templates select="//record[generate-id() = generate-id(key('vrPlanId', column[@name='VRPlanId'])[1])]" />
所以output
模板修改为
<xsl:template match="output">
<xsl:copy>
<Cdo>
<parameters>
<xsl:apply-templates select="//record[generate-id() = generate-id(key('vrPlanId', column[@name='VRPlanId'])[1])]" />
</parameters>
</Cdo>
</xsl:copy>
</xsl:template>
对于 record
模板,检查 MSSinergieTaskP
或 MSSinergieTaskNP
中是否有任何值,然后循环遍历分组节点以从 MSSinergieTaskP
中获取值。
下面是完整的 XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:key name="vrPlanId" match="record" use="column[@name='VRPlanId']" />
<xsl:template match="output">
<xsl:copy>
<Cdo>
<parameters>
<xsl:apply-templates select="//record[generate-id() = generate-id(key('vrPlanId', column[@name='VRPlanId'])[1])]" />
</parameters>
</Cdo>
</xsl:copy>
</xsl:template>
<xsl:template match="record">
<xsl:if test="column[@name='MSSinergieTaskP'] != '' or column[@name='MSSinergieTaskNP'] != ''">
<action>
<xsl:attribute name="id">
<xsl:value-of select="column[@name='VRPlanId']" />
</xsl:attribute>
</action>
<xsl:for-each select="key('vrPlanId', column[@name='VRPlanId'])">
<task>
<xsl:attribute name="id">
<xsl:value-of select="column[@name='MSSinergieTaskP']" />
</xsl:attribute>
</task>
</xsl:for-each>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
这提供了所需的输出
<output>
<Cdo>
<parameters>
<action id="11310281" />
<task id="1319575" />
<task id="1319623" />
<task id="1319667" />
</parameters>
</Cdo>
</output>
输入:
<?xml version="1.0" encoding="UTF-8"?>
<output>
<input>
<!--details-->
</input>
<meta2>
<Comenzi>
<output_getquerydata>
<queries>
<query name="part1">
<parameters>
<!--details-->
</parameters>
<queryErrors>
<!--details-->
</queryErrors>
<queryResults>
<record id="1">
<column name="id_schedule">3</column>
<column name="VRIdTask">1319648</column>
<column name="MSSinergieOrderP"/>
<column name="MSSinergieTaskP"/>
<column name="VRPlanId">11310337</column>
<column name="TripLabel">189221</column>
<column name="MSSinergieOrderNP"/>
<column name="MSSinergieTaskNP"/>
</record>
<record id="2">
<column name="id_schedule">3</column>
<column name="VRIdTask">1319652</column>
<column name="MSSinergieOrderP">1320566</column>
<column name="MSSinergieTaskP">1319575</column>
<column name="VRPlanId">11310281</column>
<column name="TripLabel">189221</column>
<column name="MSSinergieOrderNP"/>
<column name="MSSinergieTaskNP"/>
</record>
<record id="3">
<column name="id_schedule">3</column>
<column name="VRIdTask">1319652</column>
<column name="MSSinergieOrderP">1320614</column>
<column name="MSSinergieTaskP">1319623</column>
<column name="VRPlanId">11310281</column>
<column name="TripLabel">189221</column>
<column name="MSSinergieOrderNP"/>
<column name="MSSinergieTaskNP"/>
</record>
<record id="4">
<column name="id_schedule">3</column>
<column name="VRIdTask">1319652</column>
<column name="MSSinergieOrderP">1320656</column>
<column name="MSSinergieTaskP">1319667</column>
<column name="VRPlanId">11310281</column>
<column name="TripLabel">189221</column>
<column name="MSSinergieOrderNP"/>
<column name="MSSinergieTaskNP"/>
</record>
</queryResults>
</query>
</queries>
</output_getquerydata>
</Comenzi>
</meta2>
</output>
XSL:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" />
<xsl:template name="task-attr">
<!--parameter to filter per VRPlanId-->
<xsl:param name="param.VRPlanId"/>
<xsl:variable name="var.mstp">
<xsl:for-each
select="/output/meta2/Comenzi/output_getquerydata/queries/query/queryResults/rec
ord[column[@name='VRPlanId'] = $param.VRPlanId]">
<!--preventing empty blocks and duplicates for MSTP-->
<xsl:if test="string-length(column[@name='MSSinergieTaskP']) >0
and not(preceding::record[column[@name='MSSinergieTaskP']/text() =
current()/column[@name='MSSinergieTaskP']/text()])">
<xsl:value-of select="concat(column[@name='MSSinergieTaskP'],
',')"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="var.msonpc">
<xsl:for-each
select="/output/meta2/Comenzi/output_getquerydata/queries/query/queryResults/re
cord[column[@name='VRPlanId'] = $param.VRPlanId]">
<!--preventing empty blocks and duplicates for MSONPC-->
<xsl:if test="string-length(column[@name='MSSinergieTaskNP']) >0
and not(preceding::record[column[@name='MSSinergieTaskNP']/text() =
current()/column[@name='MSSinergieTaskNP']/text()])">
<xsl:value-of select="concat(column[@name='MSSinergieTaskNP'],
',')"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<!--concat all non-duplicates MSTP and MSONPC without last delimiter-->
<xsl:value-of select="concat($var.mstp, substring($var.msonpc, 1, string-
length($var.msonpc)-1))"/>
</xsl:template>
<xsl:template match="/">
<output>
<xsl:for-each
select="/output/meta2/Comenzi/output_getquerydata/queries/query/queryResults/record">
<xsl:if test ="not(preceding::record[column[@name='VRPlanId']/text() =
current()/column[@name='VRPlanId']/text()])">
<xsl:variable name="task.id">
<xsl:call-template name="task-attr">
<!--as input parameter put non-duplicate VRPlanId-->
<xsl:with-param name="param.VRPlanId"
select="column[@name='VRPlanId']"/>
</xsl:call-template>
</xsl:variable>
<!--if all non-duplicates MSTP and MSONPC will be blank block
Cdo won't be created-->
<xsl:if test="string-length($task.id) >0">
<Cdo>
<parameters>
<task>
<xsl:attribute name="id">
<xsl:value-of select="$task.id"/>
</xsl:attribute>
</task>
<action>
<xsl:attribute name="id">
<xsl:value-of
select="column[@name='VRPlanId']"/>
</xsl:attribute>
</action>
</parameters>
</Cdo>
</xsl:if>
</xsl:if>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
大家好,
感谢您的帮助。 目标是检查我们构建标签的每个不同的 VRPlanID 值 如果标签的 id 部分中没有 null/empty,则将相应的 MSTP、MSONPC(不同)分组。 因此,我们在 VRPlanID 之后分组,然后从 MSTP/MSONPC 中的每条记录中获取不同的值。 如果它们是空的,那么只需构建一个虚拟/空 message/tag。 这有效,但我有 2 个问题: - 我总是在最后一个 ID 后得到一个 ',' 逗号,我不明白为什么 - 我不再需要串联,但我想为每个 ID 设置一个标签任务
因此,所需的输出将是:
<output>
<Cdo>
<parameters>
<task id="1319575"/>
<task id="1319623"/>
<task id="1319667"/>
<action id="11310281"/>
</parameters>
</Cdo>
</output>
请记住,标签 MSInergieTaskP 和 MSInergieTaskNP 之间的任何组合都是可能的。所以一个可能是空的,另一个不是。或者只为一条记录留空,然后为下一条记录提供值。 我只是想为每个不同的 VRIdTask 获取任何组合的不同值。
我似乎无法让它工作。 请问有什么建议吗?
对于 XSLT 1.0 中的分组,最有效的解决方案是使用 muenchian grouping。
在这种情况下,您可以使用属性 @name='VRPlanId'
.
<xsl:key name="vrPlanId" match="record" use="column[@name='VRPlanId']" />
然后使用键对节点进行分组
<xsl:apply-templates select="//record[generate-id() = generate-id(key('vrPlanId', column[@name='VRPlanId'])[1])]" />
所以output
模板修改为
<xsl:template match="output">
<xsl:copy>
<Cdo>
<parameters>
<xsl:apply-templates select="//record[generate-id() = generate-id(key('vrPlanId', column[@name='VRPlanId'])[1])]" />
</parameters>
</Cdo>
</xsl:copy>
</xsl:template>
对于 record
模板,检查 MSSinergieTaskP
或 MSSinergieTaskNP
中是否有任何值,然后循环遍历分组节点以从 MSSinergieTaskP
中获取值。
下面是完整的 XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:key name="vrPlanId" match="record" use="column[@name='VRPlanId']" />
<xsl:template match="output">
<xsl:copy>
<Cdo>
<parameters>
<xsl:apply-templates select="//record[generate-id() = generate-id(key('vrPlanId', column[@name='VRPlanId'])[1])]" />
</parameters>
</Cdo>
</xsl:copy>
</xsl:template>
<xsl:template match="record">
<xsl:if test="column[@name='MSSinergieTaskP'] != '' or column[@name='MSSinergieTaskNP'] != ''">
<action>
<xsl:attribute name="id">
<xsl:value-of select="column[@name='VRPlanId']" />
</xsl:attribute>
</action>
<xsl:for-each select="key('vrPlanId', column[@name='VRPlanId'])">
<task>
<xsl:attribute name="id">
<xsl:value-of select="column[@name='MSSinergieTaskP']" />
</xsl:attribute>
</task>
</xsl:for-each>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
这提供了所需的输出
<output>
<Cdo>
<parameters>
<action id="11310281" />
<task id="1319575" />
<task id="1319623" />
<task id="1319667" />
</parameters>
</Cdo>
</output>