基于标题或文档条目使用xslt对XML进行分组
对于下面的XML代码,如何使用xlst对XML进行分组。 以下是输入XML:我使用这个输入XML来导入ERP系统基于标题或文档条目使用xslt对XML进行分组,xslt,Xslt,对于下面的XML代码,如何使用xlst对XML进行分组。 以下是输入XML:我使用这个输入XML来导入ERP系统 <row> <Ref>1</Ref> <Code>IT001</Code> <Qty>11</Qty> </row> <row> <Ref>1</Ref>
<row>
<Ref>1</Ref>
<Code>IT001</Code>
<Qty>11</Qty>
</row>
<row>
<Ref>1</Ref>
<Code>IT002</Code>
<Qty>21</Qty>
</row>
<row>
<Ref>2</Ref>
<Code>IT002</Code>
<Qty>12</Qty>
</row>
以下是输出或预期的XML:ERP系统通常接受每个文档的一行及其文档行的同级。因此,需要以下所需输出
<Document>
<Ref>1</Ref><Lines>
<Item>
<Code>IT001</Code>
<Qty>11</Qty>
</Item>
<Item>
<Code>IT002</Code>
<Qty>21</Qty>
</Item>
</Lines>
</Document>
<Document>
<OrderRef>2</OrderRef>
<Lines>
<Item>
<Code>IT002</Code>
<Qty>12</Qty>
</Item>
</Lines>
</Document>
让我们从更正源XML开始: 必须只有一个根元素(我称之为根) 其中可以有多个(如文档)元素 执行转换的模板应与 根元素 正如我从预期输出中看到的,您希望对文档进行分组 元素,因此在下面的脚本中 每个组指令对应的xsl: 对于每个这样的组,都应该有文档输出元素 在它的内部有一个Ref元素和当前值 分组键 然后应该有一个Lines元素,在其中,每个 当前组的成员,应该有Item元素 在它里面有两个子元素,它们的值是 源元素 因此,整个脚本可以如下所示:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="Root">
<xsl:copy>
<xsl:for-each-group select="Document" group-by="DocumentRef">
<Document>
<Ref><xsl:value-of select="current-grouping-key()"/></Ref>
<Lines>
<xsl:for-each select="current-group()">
<Item>
<ItemCode><xsl:value-of select="DocumentLines/ItemCode"/></ItemCode>
<Qty><xsl:value-of select="DocumentLines/ItemQty"/></Qty>
</Item>
</xsl:for-each>
</Lines>
</Document>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:transform>
它在上“调用操作”(在本例中为xsl:apply templates
)
每组中的第一个对象
我的初始解决方案中的其余代码已移至
与行匹配的模板
它的初始部分为当前组执行操作
(生成输出文档、参考、卡片代码和行)
元素)
其余的(xsl:for each
)为单个
当前组的成员、生成项、项代码
和数量元素
我在xsltransform中更新了您的解决方案,因此您可以查看
穿上
注意,我将XSLT引擎更改为Saxon 6.5.5。你也可以
将其切换到Xalan,尽管这样会使缩进变松
如果这种方法对你来说是新的,也许你应该读一些关于
生成id和Muenchian分组本身。即使StackOverflow也包含
关于这些问题的帖子很多。请发布您的XSL,即使它不起作用。请参阅。请在问题本身中发布所有代码(XML、XSLT、预期输出)。您好@Valdi_-Bo,我的应用程序不支持XSL版本2.0,因此不支持每个组的XSL:。有没有办法用XSL 1.0版本实现同样的功能?Hi@Valdi_Bo修改了工作副本以匹配我的精确输入xml。顺便说一下,我使用了您的xslt语句,它工作得很好。但我的应用程序不支持xsl 2.0版,因此不支持每个组的xsl:for。XSL工作副本在这里。
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:key name="groups" match="row" use="OrderRef"/>
<xsl:template match="Payload">
<xsl:copy>
<xsl:apply-templates select="row[generate-id() = generate-id(
key('groups', OrderRef)[1])]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="row">
<Document>
<Ref><xsl:value-of select="OrderRef"/></Ref>
<CardCode><xsl:value-of select="CustomerCode"/></CardCode>
<Lines>
<xsl:for-each select="key('groups', OrderRef)">
<Item>
<ItemCode><xsl:value-of select="ItemCode"/></ItemCode>
<Qty><xsl:value-of select="Quantity"/></Qty>
</Item>
</xsl:for-each>
</Lines>
</Document>
</xsl:template>
</xsl:transform>
<xsl:apply-templates select="row[generate-id() = generate-id(
key('groups', OrderRef)[1])]"/>