[英]Merging tags based on two different complex tags
In the below two ASNInPO's po_nbr is same container_id under ASNInCtn is same and item_id under ASNInItem is different. 在下面的两个ASNInPO的po_nbr中,ASNInCtn下的container_id相同,而ASNInItem下的item_id不同。 In this case two ASNInPO's has to be merged and two ASNInCtn's has to be merged into one tag.
在这种情况下,两个ASNInPO必须合并,而两个ASNInCtn必须合并为一个标签。 This is my Input:
这是我的输入:
<?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>
This is the desired output: 这是所需的输出:
<?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>
Please help me in solving this. 请帮我解决这个问题。
Since this question is tagged with xslt-1.0
, I'll post a XSLT 1.0 solution using the Muenchian grouping method. 由于此问题用
xslt-1.0
标记,因此我将使用Muenchian分组方法发布XSLT 1.0解决方案。 (Perhaps someone else will contribute a XSLT 2.0 solution. It might be instructive to compare them.) (也许其他人会提供XSLT 2.0解决方案。将它们进行比较可能很有帮助。)
Let's walk through the stylesheet. 让我们浏览样式表。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
ASNInPO
elements by po_nbr
po_nbr
ASNInPO
元素 Since we want to group ASNInPO
elements by their po_nbr
, let's start by defining a key which allows retrieving ASNInPO
elements by their po_nbr
value. 由于我们
ASNInPO
元素的po_nbr
,因此我们首先定义一个键 ,该键允许按po_nbr
值检索ASNInPO
元素。
<xsl:key name="ASNInPO-by-po_nbr"
match="ASNInPO" use="po_nbr"/>
Then we'll write a template which matches an ASNInDesc
. 然后,我们将编写一个与
ASNInDesc
匹配的ASNInDesc
。 We'll make a copy of the element, along with its asn_nbr
. 我们将复制该元素及其
asn_nbr
。 Now we want to group the contained ASNInPO
elements by their po_nbr
. 现在,我们要按其
po_nbr
将包含的ASNInPO
元素po_nbr
。 We do this by applying templates to the first ASNInPo
in each group: 为此,我们将模板应用于每个组中的第一个
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>
ASNInCtn
elements by container_id
container_id
ASNInCtn
元素 But before we go further, we'll need to define another key. 但是在继续之前,我们需要定义另一个键。 It seems like we need to group
ASNInCtn
elements by their container_id
(see note below if this is not the case). 好像我们需要组
ASNInCtn
由它们的元素container_id
(参见下面的注释,如果不是这种情况)。
<xsl:key name="ASNInCtn-by-container_id"
match="ASNInCtn" use="container_id"/>
We'll need that key in the following template which matches ASNInPO
elements. 我们需要以下模板中与
ASNInPO
元素匹配的ASNInPO
。 Remember that the elements we process here will be the first ones of their group, since we selected only those in the xsl:apply-template
above. 请记住,由于我们仅在上面的
xsl:apply-template
选择了元素,因此我们在此处处理的元素将是它们中的第一个元素。
This template is similar to the one we wrote above. 这个模板类似于我们上面写的模板。 We make copy of the element itself along with its
po_nbr
and then again apply templates to the first ASNInCtn
elements grouped by their container_id
: 我们复制元素本身及其
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>
Finally, we write the template which matches ASNInCtn
elements. 最后,我们编写与
ASNInCtn
元素匹配的模板。 This copies the element itself, and its container_id
and then copies all ASNInItem
elements in the same group : 这将复制元素本身及其
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>
And we're done. 我们完成了。
</xsl:stylesheet>
The solution assumes that the ASNInCtn
element with a given container_id
can only appear within ASNInPO
elements with the same po_nbr
. 该解决方案假定
ASNInCtn
与给定元件container_id
可以内只能出现ASNInPO
与相同的元件po_nbr
。 If this is not the case, then you need to adjust the key for ASNInPO
objects to use a combination of po_nbr
and container_id
. 如果不是这种情况,则需要调整
ASNInPO
对象的键以使用po_nbr
和container_id
的组合。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.