分组节点在三个层面上,总结一个节点(Grouping the nodes at three leve

2019-09-20 02:42发布

请按照示例XML注释它解释了我需要的一切,它有三个之情况的检查在同一顺序输出XML各之情况。

输入XML

   <!-- In the below xml there will be one ASNInDesc with multiple ASNInPO's 
        and each ASNInPO contains one ASNInCtn and each ASNInCtn contains one ASNInItem -->

<ASNInDesc>
   <asn_nbr>ASN-1</asn_nbr>

   <!-- In the below two ASNInPO's po_nbr is same container_id under ASNInCtn is same and item_id under
        ASNInItem is same. In this case two ASNInPO's has to be merged and two ASNInCtn's has to be merged
        into one tag(since the container_id is same) and two ASNInItem's has to be merged into one tag and unit_qty is to be added  -->

   <ASNInPO>
      <po_nbr>PO-1</po_nbr>
      <ASNInCtn>
         <container_id>CONTAINER-1</container_id>
         <ASNInItem>
            <item_id>ITEM-1</item_id>
            <unit_qty>2</unit_qty>
         </ASNInItem>
      </ASNInCtn>
   </ASNInPO>
   <ASNInPO>
      <po_nbr>PO-1</po_nbr>
      <ASNInCtn>
         <container_id>CONTAINER-1</container_id>
         <ASNInItem>
            <item_id>ITEM-1</item_id>
            <unit_qty>2</unit_qty>
         </ASNInItem>
      </ASNInCtn>
   </ASNInPO>

   <!-- In the below two ASNInPO's po_nbr is same container_id under ASNInCtn is same and item_id under
        ASNInItem is different. In this case two ASNInPO's has to be merged and two ASNInCtn's has to be merged into one tag and
        two different ASNInItem's for the two different items  -->

    <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>

   <!-- In the below two ASNInPO's po_nbr is same container_id under ASNInCtn is different and item_id under
        ASNInItem is different. In this case two ASNInPO's has to be merged into one tag with
        two different ASNInCtn's each having their own ASNInItem  -->

   <ASNInPO>
      <po_nbr>PO-3</po_nbr>
      <ASNInCtn>
         <container_id>CONTAINER-3</container_id>
         <ASNInItem>
            <item_id>ITEM-3</item_id>
            <unit_qty>2</unit_qty>
         </ASNInItem>
      </ASNInCtn>
   </ASNInPO>
   <ASNInPO>
      <po_nbr>PO-3</po_nbr>
      <ASNInCtn>
         <container_id>CONTAINER-4</container_id>
         <ASNInItem>
            <item_id>ITEM-3</item_id>
            <unit_qty>2</unit_qty>
         </ASNInItem>
      </ASNInCtn>
   </ASNInPO>

</ASNInDesc>

输出XML

<?xml version = '1.0' encoding = 'UTF-8'?>
<ASNInDesc>
   <asn_nbr>ASN-1</asn_nbr>
  <!-- Scenerio-1 --> 
   <ASNInPO>
      <po_nbr>PO-1</po_nbr>
      <ASNInCtn>
         <container_id>CONTAINER-1</container_id>
         <ASNInItem>
            <item_id>ITEM-1</item_id>
            <unit_qty>4</unit_qty>
         </ASNInItem>        
      </ASNInCtn>
  </ASNInPO>
  <!-- Scenerio-2 -->  
  <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>
  <!-- Scenerio-3 -->   
   <ASNInPO>
      <po_nbr>PO-3</po_nbr>
      <ASNInCtn>
         <container_id>CONTAINER-3</container_id>
         <ASNInItem>
            <item_id>ITEM-3</item_id>
            <unit_qty>2</unit_qty>
         </ASNInItem>
      </ASNInCtn>
      <ASNInCtn>
         <container_id>CONTAINER-4</container_id>
         <ASNInItem>
            <item_id>ITEM-3</item_id>
            <unit_qty>2</unit_qty>
         </ASNInItem>
      </ASNInCtn>     
   </ASNInPO>

我试图用我自己的XSL,但无法处理所有的scenerios。 请帮我解决这个。 提前致谢。

Answer 1:

下面是一个使用XSLT 1.0样式Muenchian分组的 。 这是基于我的回答你的其他问题。

这是同样的方法,但在这里我们使用元素自己的ID和父元素的ID的串联来查找分组元素调节键。 例如, ASNInItem元件抬头使用以下级联键: concat(../../po_nbr, '|', ../container_id, '|', item_id) 分离器的选择并不重要,但你需要选择哪个没有出现在id的字符。

此外单价求和已被添加。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

  <xsl:key name="ASNInPO" match="ASNInPO" 
           use="po_nbr"/>

  <xsl:key name="ASNInCtn" match="ASNInCtn" 
           use="concat(../po_nbr, '|', 
                       container_id)"/>

  <xsl:key name="ASNInItem" match="ASNInItem" 
           use="concat(../../po_nbr, '|', 
                       ../container_id, '|', 
                       item_id)"/>

  <xsl:template match="ASNInDesc">
    <xsl:copy>
      <xsl:copy-of select="asn_nbr"/>
      <xsl:apply-templates 
          select="ASNInPO[generate-id() =
                          generate-id(key('ASNInPO', 
                                          po_nbr)[1])]"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="ASNInPO">
    <xsl:copy>
      <xsl:copy-of select="po_nbr"/>
      <xsl:apply-templates 
          select="key('ASNInPO', po_nbr)/
                  ASNInCtn[generate-id() =
                           generate-id(key('ASNInCtn',
                                           concat(../po_nbr, '|', 
                                                  container_id))[1])]"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="ASNInCtn">
    <xsl:copy>
      <xsl:copy-of select="container_id"/>
      <xsl:apply-templates
          select="key('ASNInCtn',
                      concat(../po_nbr, '|', 
                             container_id))/
                  ASNInItem[generate-id() =
                            generate-id(key('ASNInItem', 
                                        concat(../../po_nbr, '|',
                                               ../container_id, '|',
                                               item_id))[1])]"/>
    </xsl:copy>
  </xsl:template>


  <xsl:template match="ASNInItem">
    <xsl:copy>
      <xsl:copy-of select="item_id"/>
      <unit_qty>
        <xsl:value-of 
            select="sum(key('ASNInItem', 
                        concat(../../po_nbr, '|', 
                               ../container_id, '|', 
                               item_id))/unit_qty)"/>
      </unit_qty>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>


文章来源: Grouping the nodes at three levels and summing one node