在下面的两个ASNInPO中,po_nbr相同container_id ASNInCtn下相同,ASNInItem 下的item_id是不同的。在这种情况下,必须合并两个 ASNInPO,并且必须将两个 ASNInCtn 合并到一个标签中。这是我的输入:
<?xml version = '1.0' encoding = 'UTF-8'?>
<ASNInDesc>
<asn_nbr>ASN-1</asn_nbr>
<ASNInPO>
<po_nbr>PO-2</po_nbr>
<ASNInCtn>
<container_id>CONTAINER-2</container_id>
<ASNInItem>
<item_id>ITEM-2</item_id>
<unit_qty>3</unit_qty>
</ASNInItem>
</ASNInCtn>
</ASNInPO>
<ASNInPO>
<po_nbr>PO-2</po_nbr>
<ASNInCtn>
<container_id>CONTAINER-2</container_id>
<ASNInItem>
<item_id>ITEM-3</item_id>
<unit_qty>3</unit_qty>
</ASNInItem>
</ASNInCtn>
</ASNInPO>
</ASNInDesc>
这是所需的输出:
<?xml version = '1.0' encoding = 'UTF-8'?>
<ASNInDesc>
<asn_nbr>ASN-1</asn_nbr>
<ASNInPO>
<po_nbr>PO-2</po_nbr>
<ASNInCtn>
<container_id>CONTAINER-2</container_id>
<ASNInItem>
<item_id>ITEM-2</item_id>
<unit_qty>3</unit_qty>
</ASNInItem>
<ASNInItem>
<item_id>ITEM-3</item_id>
<unit_qty>3</unit_qty>
</ASNInItem>
</ASNInCtn>
</ASNInPO>
</ASNInDesc>
请帮助我解决这个问题。
由于这个问题被标记为 xslt-1.0
,我将发布一个 XSLT1.0 使用明基分组方法的解决方案。(也许有人else 将贡献一个 XSLT 2.0 解决方案。它可能是有启发性的比较它们。
让我们浏览一下样式表。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
分组 1:按po_nbr
ASNInPO
元素
既然我们想按元素po_nbr
对元素进行分组ASNInPO
,让我们首先定义一个允许检索ASNInPO
的键元素的po_nbr
值。
<xsl:key name="ASNInPO-by-po_nbr"
match="ASNInPO" use="po_nbr"/>
然后我们将编写一个与ASNInDesc
匹配的模板。我们将制作一个元素的副本及其asn_nbr
.现在我们要分组所包含的ASNInPO
元素按其po_nbr
.我们通过以下方式做到这一点将模板应用于每个组中的第一个ASNInPo
:
<xsl:template match="ASNInDesc">
<xsl:copy>
<xsl:copy-of select="asn_nbr"/>
<xsl:apply-templates select="ASNInPO[generate-id() =
generate-id(key('ASNInPO-by-po_nbr',
po_nbr)[1])]"/>
</xsl:copy>
</xsl:template>
分组 2:按container_id
ASNInCtn
元素
但在进一步讨论之前,我们需要定义另一个键。似乎就像我们需要按元素container_id
对元素进行分组ASNInCtn
(如果不是这种情况,请参阅下面的注释(。
<xsl:key name="ASNInCtn-by-container_id"
match="ASNInCtn" use="container_id"/>
我们将在以下模板中需要与ASNInPO
匹配的密钥元素。请记住,我们在这里处理的元素将是第一个他们小组中的一个,因为我们只选择了那些 xsl:apply-template
上文。
这个模板类似于我们上面写的模板。我们制作副本元素本身及其po_nbr
,然后再次应用模板到按其分组的前ASNInCtn
元素 container_id
:
<xsl:template match="ASNInPO">
<xsl:copy>
<xsl:copy-of select="po_nbr"/>
<xsl:apply-templates select="key('ASNInPO-by-po_nbr', po_nbr)/
ASNInCtn[generate-id() =
generate-id(key('ASNInCtn-by-container_id',
container_id)[1])]"/>
</xsl:copy>
</xsl:template>
最后,我们编写与ASNInCtn
元素匹配的模板。这复制元素本身及其container_id
,然后复制所有 ASNInItem
同一组中的元素:
<xsl:template match="ASNInCtn">
<xsl:copy>
<xsl:copy-of select="container_id"/>
<xsl:copy-of select="key('ASNInCtn-by-container_id',
container_id)/ASNInItem"/>
</xsl:copy>
</xsl:template>
我们完成了。
</xsl:stylesheet>
注意
该解决方案假定ASNInCtn
元素具有给定的 container_id
只能出现在具有相同ASNInPO
元素中 po_nbr
.如果不是这种情况,则需要调整键 ASNInPO
对象以使用 po_nbr
和 container_id
的组合。