使用 XSLT 中的某些键合并数据
Consolidation of Data using certain keys in XSLT
我有一个输入XML文件:
<root>
<row>
<col1>cust001</col1>
<col2>cc1</col2>
<col3>po1</col3>
<col4>2020-02-22</col4>
<col5>Men</col5>
<col6>item1</col6>
<col7>60</col7>
</row>
<row>
<col1>cust001</col1>
<col2>cc1</col2>
<col3>po1</col3>
<col4>2020-02-22</col4>
<col5>Men</col5>
<col6>item2</col6>
<col7>50</col7>
</row>
</root>
期望输出:(如果 col1 到 col5 相同,则合并为一行。)
<root>
<row>
<col1>cust001</col1>
<col2>cc1</col2>
<col3>po1</col3>
<col4>2020-02-22</col4>
<col5>Men</col5>
<col6>item1</col6>
<col7>60</col7>
<col6>item2</col6>
<col7>50</col7>
</row>
</root>
我正在尝试这里的代码 XSLT Consolidating data when ID is the same 但我得到了,表达式当前组错误():未知系统函数:当前组。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.castiron.com//response">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="resultSets">
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
<xsl:template match="resultSet">
<xsl:apply-templates select="@*"/>
<xsl:for-each-group select="root/row" group-by="concat(col1,col2,col3,col4,col5)">
<xsl:value-of select="current-grouping-key()"/>
<xsl:apply-templates select="current-group()" />
</xsl:for-each-group>
</xsl:template>
假设您使用 XSLT 3 处理器,如 Saxon 9.8 或更高版本或 AltovaXML 2017 R3 或更高版本,您可以使用要用作分组键的元素的复合分组键,那么在内部,您当然需要确保为每个组创建一个 row
并且只处理一次构成分组键的项目(例如,对于组中的第一个项目,它是 for-each-group
内的上下文项目),然后组中所有项目的所有其他元素:
<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:output indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="root">
<xsl:copy>
<xsl:for-each-group select="row" composite="yes" group-by="col1, col2, col3, col4, col5">
<xsl:copy>
<xsl:apply-templates select="col1, col2, col3, col4, col5, current-group()/(* except (col1, col2, col3, col4, col5))"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/jz1Q1yt
或者,也许 for-each-group
的正文在
的分组关键元素方面重复性较低
<xsl:template match="root">
<xsl:copy>
<xsl:for-each-group select="row!copy-of()" composite="yes" group-by="col1, col2, col3, col4, col5">
<xsl:copy>
<xsl:apply-templates select="current-group()/(if (position() eq 1) then * else (* except (col1, col2, col3, col4, col5)))"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
我有一个输入XML文件:
<root>
<row>
<col1>cust001</col1>
<col2>cc1</col2>
<col3>po1</col3>
<col4>2020-02-22</col4>
<col5>Men</col5>
<col6>item1</col6>
<col7>60</col7>
</row>
<row>
<col1>cust001</col1>
<col2>cc1</col2>
<col3>po1</col3>
<col4>2020-02-22</col4>
<col5>Men</col5>
<col6>item2</col6>
<col7>50</col7>
</row>
</root>
期望输出:(如果 col1 到 col5 相同,则合并为一行。)
<root>
<row>
<col1>cust001</col1>
<col2>cc1</col2>
<col3>po1</col3>
<col4>2020-02-22</col4>
<col5>Men</col5>
<col6>item1</col6>
<col7>60</col7>
<col6>item2</col6>
<col7>50</col7>
</row>
</root>
我正在尝试这里的代码 XSLT Consolidating data when ID is the same 但我得到了,表达式当前组错误():未知系统函数:当前组。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.castiron.com//response">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="resultSets">
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
<xsl:template match="resultSet">
<xsl:apply-templates select="@*"/>
<xsl:for-each-group select="root/row" group-by="concat(col1,col2,col3,col4,col5)">
<xsl:value-of select="current-grouping-key()"/>
<xsl:apply-templates select="current-group()" />
</xsl:for-each-group>
</xsl:template>
假设您使用 XSLT 3 处理器,如 Saxon 9.8 或更高版本或 AltovaXML 2017 R3 或更高版本,您可以使用要用作分组键的元素的复合分组键,那么在内部,您当然需要确保为每个组创建一个 row
并且只处理一次构成分组键的项目(例如,对于组中的第一个项目,它是 for-each-group
内的上下文项目),然后组中所有项目的所有其他元素:
<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:output indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="root">
<xsl:copy>
<xsl:for-each-group select="row" composite="yes" group-by="col1, col2, col3, col4, col5">
<xsl:copy>
<xsl:apply-templates select="col1, col2, col3, col4, col5, current-group()/(* except (col1, col2, col3, col4, col5))"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/jz1Q1yt
或者,也许 for-each-group
的正文在
<xsl:template match="root">
<xsl:copy>
<xsl:for-each-group select="row!copy-of()" composite="yes" group-by="col1, col2, col3, col4, col5">
<xsl:copy>
<xsl:apply-templates select="current-group()/(if (position() eq 1) then * else (* except (col1, col2, col3, col4, col5)))"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>