简体   繁体   English

基于两个不同的复杂标签合并标签

[英]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"/>

Grouping 1: ASNInPO elements by po_nbr 分组1:按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>

Grouping 2: ASNInCtn elements by container_id 分组2:按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>

Note 注意

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_nbrcontainer_id的组合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM