在下面两个示例中,ASNInPO的po_nbr是相同的,ASNInCtn下的container_id是相同的,而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>请帮我解决这个问题。
发布于 2012-08-02 13:47:14
因为这个问题是用xslt-1.0标记的,所以我将使用方法发布一个XSLT1.0解决方案。(也许其他人会贡献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元素
由于我们希望根据ASNInPO元素的po_nbr对其进行分组,因此让我们首先定义一个,它允许根据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元素
但是在我们继续之前,我们需要定义另一个键。似乎我们需要根据ASNInCtn元素的container_id对其进行分组(如果不是这样,请参阅下面的注释)。
<xsl:key name="ASNInCtn-by-container_id"
match="ASNInCtn" use="container_id"/>我们需要在下面的模板中找到匹配ASNInPO元素的键。记住,我们在这里处理的元素将是它们组中的第一个元素,因为我们只选择了上面xsl:apply-template中的那些元素。
此模板与我们上面编写的模板类似。我们复制元素本身及其po_nbr,然后再次将模板应用于按container_id分组的第一个ASNInCtn元素
<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>备注
该解决方案假设具有给定container_id的ASNInCtn元素只能出现在具有相同po_nbr的ASNInPO元素中。如果不是这样,则需要调整ASNInPO对象的键,以组合使用po_nbr和container_id。
https://stackoverflow.com/questions/11753150
复制相似问题