XSLT 2.0 中的变量分组
Grouping of variables in XSLT 2.0
对于具有相同值 <CtryCd>
的每个 <LineDetail>
节点,并用 <Amt>
的总和填充 1 <LineDetail>
。
但是,我还需要检查 <SI>
和 <TI>
节点。求和的输出标签将基于 <SI>
和 <TI>
节点。如果<SI>
和<TI>
的值都为false,则生成<Amt1>
,而如果<SI>
的值为true且[=19,则生成<Amt2>
=] 是错误的。
我创建了一个 XSLT 并且已经得到了总和。但是我的输出中仍然缺少一些东西。
这是一个示例XML:
<Record>
<Data>
<Process>
<Header>
<ID>22-BBB</ID>
<Date>2017-02-14</Date>
<ContactName>Abegail</ContactName>
<!-- some other elements -->
</Header>
<Detail>
<ID>22-CCC</ID>
<RequestedDate>2017-02-14</RequestedDate>
<!-- some other elements -->
<LineDetail>
<CtryCd>AF</CtryCd>
<SI>false</SI>
<TI>false</TI>
<Amt>11.11</Amt>
</LineDetail>
<LineDetail>
<CtryCd>SE</CtryCd>
<SI>true</SI>
<TI>false</TI>
<Amt>22.22</Amt>
</LineDetail>
<LineDetail>
<CtryCd>AF</CtryCd>
<SI>false</SI>
<TI>false</TI>
<Amt>33.33</Amt>
</LineDetail>
<LineDetail>
<CtryCd>AF</CtryCd>
<SI>true</SI>
<TI>false</TI>
<Amt>55.55</Amt>
</LineDetail>
</Detail>
</Process>
</Data>
</Record>
生成的输出:
<Record>
<Data>
<Process>
<Header>
<ID>22-BBB</ID>
<Date>2017-02-14</Date>
<ContactName>Abegail</ContactName>
<!-- some other elements -->
</Header>
<Detail>
<LineDetail>
<CtryCd>AF</CtryCd>
<Amt1>99.99</Amt1>
</LineDetail>
</Detail>
<Detail>
<LineDetail>
<C<Amt2>22.22</Amt2>
</LineDetail>
</Detail>
</Process>
</Data>
</Record>
预期输出:
<Record>
<Data>
<Process>
<Header>
<ID>22-BBB</ID>
<Date>2017-02-14</Date>
<ContactName>Abegail</ContactName>
<!-- some other elements -->
</Header>
<Detail>
<ID>22-CCC</ID>
<RequestedDate>2017-02-14</RequestedDate>
<!-- some other elements -->
<LineDetail>
<CtryCd>AF</CtryCd>
<Amt1>44.44</<Amt1>
<Amt2>55.55</Amt2>
</LineDetail>
<LineDetail>
<CtryCd>SE</CtryCd>
<Amt1>0</<Amt1>
<Amt2>22.22</Amt2>
</LineDetail>
</Detail>
</Process>
</Data>
</Record>
XSLT:
<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:strip-space elements="*"/>
<xsl:key name="CtryCd" match="LineDetail" use="CtryCd"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Detail">
<xsl:for-each-group select="LineDetail" group-by="CtryCd">
<Detail>
<LineDetail>
<CtryCd>
<xsl:value-of select="CtryCd"/>
</CtryCd>
<xsl:if test="lower-case(SI)='false' and lower-case(TI)='false'">
<Amt1>
<xsl:value-of select="sum(current-group()/Amt)"/>
</Amt1>
<xsl:if test="lower-case(SI)='true' and lower-case(TI)='false'">
<Amt2>
<xsl:value-of select="sum(current-group()/Amt)"/>
</Amt2>
</xsl:if>
</xsl:if>
<xsl:if test="lower-case(SI)='true' and lower-case(TI)='false'">
<Amt2>
<xsl:value-of select="sum(current-group()/Amt)"/>
</Amt2>
</xsl:if>
</LineDetail>
</Detail>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
您当前的 if 条件只会检查组中的第一项。您确实需要它成为实际总和语句的一部分,作为组中每个节点的条件。
<Amt1>
<xsl:value-of select="sum(current-group()[lower-case(SI)='false' and lower-case(TI)='false']/Amt)"/>
</Amt1>
然后您会对 Amt2
进行类似的声明,测试 "true" 和 "false"
试试这个 XSLT
<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:strip-space elements="*"/>
<xsl:key name="CtryCd" match="LineDetail" use="CtryCd"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Detail">
<xsl:for-each-group select="LineDetail" group-by="CtryCd">
<Detail>
<LineDetail>
<CtryCd>
<xsl:value-of select="CtryCd"/>
</CtryCd>
<Amt1>
<xsl:value-of select="sum(current-group()[lower-case(SI)='false' and lower-case(TI)='false']/Amt)"/>
</Amt1>
<Amt2>
<xsl:value-of select="sum(current-group()[lower-case(SI)='true' and lower-case(TI)='false']/Amt)"/>
</Amt2>
</LineDetail>
</Detail>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
对于具有相同值 <CtryCd>
的每个 <LineDetail>
节点,并用 <Amt>
的总和填充 1 <LineDetail>
。
但是,我还需要检查 <SI>
和 <TI>
节点。求和的输出标签将基于 <SI>
和 <TI>
节点。如果<SI>
和<TI>
的值都为false,则生成<Amt1>
,而如果<SI>
的值为true且[=19,则生成<Amt2>
=] 是错误的。
我创建了一个 XSLT 并且已经得到了总和。但是我的输出中仍然缺少一些东西。
这是一个示例XML:
<Record>
<Data>
<Process>
<Header>
<ID>22-BBB</ID>
<Date>2017-02-14</Date>
<ContactName>Abegail</ContactName>
<!-- some other elements -->
</Header>
<Detail>
<ID>22-CCC</ID>
<RequestedDate>2017-02-14</RequestedDate>
<!-- some other elements -->
<LineDetail>
<CtryCd>AF</CtryCd>
<SI>false</SI>
<TI>false</TI>
<Amt>11.11</Amt>
</LineDetail>
<LineDetail>
<CtryCd>SE</CtryCd>
<SI>true</SI>
<TI>false</TI>
<Amt>22.22</Amt>
</LineDetail>
<LineDetail>
<CtryCd>AF</CtryCd>
<SI>false</SI>
<TI>false</TI>
<Amt>33.33</Amt>
</LineDetail>
<LineDetail>
<CtryCd>AF</CtryCd>
<SI>true</SI>
<TI>false</TI>
<Amt>55.55</Amt>
</LineDetail>
</Detail>
</Process>
</Data>
</Record>
生成的输出:
<Record>
<Data>
<Process>
<Header>
<ID>22-BBB</ID>
<Date>2017-02-14</Date>
<ContactName>Abegail</ContactName>
<!-- some other elements -->
</Header>
<Detail>
<LineDetail>
<CtryCd>AF</CtryCd>
<Amt1>99.99</Amt1>
</LineDetail>
</Detail>
<Detail>
<LineDetail>
<C<Amt2>22.22</Amt2>
</LineDetail>
</Detail>
</Process>
</Data>
</Record>
预期输出:
<Record>
<Data>
<Process>
<Header>
<ID>22-BBB</ID>
<Date>2017-02-14</Date>
<ContactName>Abegail</ContactName>
<!-- some other elements -->
</Header>
<Detail>
<ID>22-CCC</ID>
<RequestedDate>2017-02-14</RequestedDate>
<!-- some other elements -->
<LineDetail>
<CtryCd>AF</CtryCd>
<Amt1>44.44</<Amt1>
<Amt2>55.55</Amt2>
</LineDetail>
<LineDetail>
<CtryCd>SE</CtryCd>
<Amt1>0</<Amt1>
<Amt2>22.22</Amt2>
</LineDetail>
</Detail>
</Process>
</Data>
</Record>
XSLT:
<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:strip-space elements="*"/>
<xsl:key name="CtryCd" match="LineDetail" use="CtryCd"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Detail">
<xsl:for-each-group select="LineDetail" group-by="CtryCd">
<Detail>
<LineDetail>
<CtryCd>
<xsl:value-of select="CtryCd"/>
</CtryCd>
<xsl:if test="lower-case(SI)='false' and lower-case(TI)='false'">
<Amt1>
<xsl:value-of select="sum(current-group()/Amt)"/>
</Amt1>
<xsl:if test="lower-case(SI)='true' and lower-case(TI)='false'">
<Amt2>
<xsl:value-of select="sum(current-group()/Amt)"/>
</Amt2>
</xsl:if>
</xsl:if>
<xsl:if test="lower-case(SI)='true' and lower-case(TI)='false'">
<Amt2>
<xsl:value-of select="sum(current-group()/Amt)"/>
</Amt2>
</xsl:if>
</LineDetail>
</Detail>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
您当前的 if 条件只会检查组中的第一项。您确实需要它成为实际总和语句的一部分,作为组中每个节点的条件。
<Amt1>
<xsl:value-of select="sum(current-group()[lower-case(SI)='false' and lower-case(TI)='false']/Amt)"/>
</Amt1>
然后您会对 Amt2
进行类似的声明,测试 "true" 和 "false"
试试这个 XSLT
<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:strip-space elements="*"/>
<xsl:key name="CtryCd" match="LineDetail" use="CtryCd"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Detail">
<xsl:for-each-group select="LineDetail" group-by="CtryCd">
<Detail>
<LineDetail>
<CtryCd>
<xsl:value-of select="CtryCd"/>
</CtryCd>
<Amt1>
<xsl:value-of select="sum(current-group()[lower-case(SI)='false' and lower-case(TI)='false']/Amt)"/>
</Amt1>
<Amt2>
<xsl:value-of select="sum(current-group()[lower-case(SI)='true' and lower-case(TI)='false']/Amt)"/>
</Amt2>
</LineDetail>
</Detail>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>