0

下面两个 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>

请帮我解决这个问题。

4

1 回答 1

0

由于这个问题被标记为xslt-1.0,我将发布一个使用Muenchian 分组方法的 XSLT 1.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:ASNInPO元素按po_nbr

由于我们想按元素对ASNInPO元素进行分组po_nbr,让我们首先定义一个允许 按值检索元素的ASNInPOpo_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:ASNInCtn元素按container_id

但在我们更进一步之前,我们需要定义另一个键。似乎我们需要按元素对ASNInCtn元素进行分组container_id(如果不是这种情况,请参阅下面的注释)。

  <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

于 2012-08-02T05:47:14.407 回答