0

我正在尝试根据元素 ID 合并 XML 文件的子节点。例如,我有以下 XML:

<category:category.fixedChildProducts>
    <category:product repositoryId="PROD-001">
        <category:product.id>PROD-001</category:product.id>
        <category:product.childSKUs>
            <category:footwear-sku repositoryId="SKU-001">
                <category:footwear-sku.colorDefault>Black</category:footwear-sku.colorDefault>
                <category:footwear-sku.sizeDefault>Large</category:footwear-sku.sizeDefault>
            </category:footwear-sku>
            <category:footwear-sku repositoryId="SKU-002">
                <category:footwear-sku.colorDefault>Black</category:footwear-sku.colorDefault>
                <category:footwear-sku.sizeDefault>Small</category:footwear-sku.sizeDefault>
            </category:footwear-sku>
        </category:product.childSKUs>
    </category:product>
    <category:product repositoryId="PROD-001">
        <category:product.id>PROD-001</category:product.id>
        <category:product.childSKUs>
            <category:footwear-sku repositoryId="SKU-003">
                <category:footwear-sku.colorDefault>Red</category:footwear-sku.colorDefault>
                <category:footwear-sku.sizeDefault>Large</category:footwear-sku.sizeDefault>
            </category:footwear-sku>
            <category:footwear-sku repositoryId="SKU-004">
                <category:footwear-sku.colorDefault>Red</category:footwear-sku.colorDefault>
                <category:footwear-sku.sizeDefault>Small</category:footwear-sku.sizeDefault>
            </category:footwear-sku>
        </category:product.childSKUs>
    </category:product>     
</category:category.fixedChildProducts>

我需要将其转换为:

<category:category.fixedChildProducts>
    <category:product repositoryId="PROD-001">
        <category:product.id>PROD-001</category:product.id>
        <category:product.childSKUs>
            <category:footwear-sku repositoryId="SKU-001">
                <category:footwear-sku.colorDefault>Black</category:footwear-sku.colorDefault>
                <category:footwear-sku.sizeDefault>Large</category:footwear-sku.sizeDefault>
            </category:footwear-sku>
            <category:footwear-sku repositoryId="SKU-002">
                <category:footwear-sku.colorDefault>Black</category:footwear-sku.colorDefault>
                <category:footwear-sku.sizeDefault>Small</category:footwear-sku.sizeDefault>
            </category:footwear-sku>
            <category:footwear-sku repositoryId="SKU-003">
                <category:footwear-sku.colorDefault>Red</category:footwear-sku.colorDefault>
                <category:footwear-sku.sizeDefault>Large</category:footwear-sku.sizeDefault>
            </category:footwear-sku>
            <category:footwear-sku repositoryId="SKU-004">
                <category:footwear-sku.colorDefault>Red</category:footwear-sku.colorDefault>
                <category:footwear-sku.sizeDefault>Small</category:footwear-sku.sizeDefault>
            </category:footwear-sku>                
        </category:product.childSKUs>
    </category:product> 
</category:category.fixedChildProducts>

本质上,我需要遍历产品的repositoryId属性并将所有childSKUs具有相同产品的属性组合在一起repositoryId。每个产品节点都应该有一个唯一的repositoryId. 请帮忙。

4

1 回答 1

0

这是一个使用 XSL 键的 XSLT 1.0 兼容解决方案:

样式表

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:category="my:category">

  <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!-- Collect <category:product> elements into a key -->
  <xsl:key name="kProduct" match="category:product" use="@repositoryId"/>

  <!-- Identity transform -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <!--
  Match the first <category:product> element with a certain @repositoryId
  attribute value in the key.

  See http://www.jenitennison.com/xslt/grouping/muenchian.html
  -->
  <xsl:template
    match="category:product[generate-id() = 
                             generate-id(key('kProduct', @repositoryId)[1])]">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- Drop duplicate <category:product> elements -->
  <xsl:template match="category:product"/>

  <xsl:template match="category:product.childSKUs">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>

      <!--
      Apply the <category:footwear-sku> descendants of elements in the
      'kProduct' key other than the first one, which are already applied
      in the template above
      -->
      <xsl:apply-templates
        select="key('kProduct', ../@repositoryId)
                  [position() &gt; 1]/*/category:footwear-sku"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

输入

<category:category.fixedChildProducts xmlns:category="my:category">
    <category:product repositoryId="PROD-001">
        <category:product.id>PROD-001</category:product.id>
        <category:product.childSKUs>
            <category:footwear-sku repositoryId="SKU-001">
                <category:footwear-sku.colorDefault>Black</category:footwear-sku.colorDefault>
                <category:footwear-sku.sizeDefault>Large</category:footwear-sku.sizeDefault>
            </category:footwear-sku>
            <category:footwear-sku repositoryId="SKU-002">
                <category:footwear-sku.colorDefault>Black</category:footwear-sku.colorDefault>
                <category:footwear-sku.sizeDefault>Small</category:footwear-sku.sizeDefault>
            </category:footwear-sku>
        </category:product.childSKUs>
    </category:product>
    <category:product repositoryId="PROD-001">
        <category:product.id>PROD-001</category:product.id>
        <category:product.childSKUs>
            <category:footwear-sku repositoryId="SKU-003">
                <category:footwear-sku.colorDefault>Red</category:footwear-sku.colorDefault>
                <category:footwear-sku.sizeDefault>Large</category:footwear-sku.sizeDefault>
            </category:footwear-sku>
            <category:footwear-sku repositoryId="SKU-004">
                <category:footwear-sku.colorDefault>Red</category:footwear-sku.colorDefault>
                <category:footwear-sku.sizeDefault>Small</category:footwear-sku.sizeDefault>
            </category:footwear-sku>
        </category:product.childSKUs>
    </category:product>
</category:category.fixedChildProducts>

输出

<?xml version="1.0" encoding="utf-8"?>
<category:category.fixedChildProducts xmlns:category="my:category">
  <category:product repositoryId="PROD-001">
    <category:product.id>PROD-001</category:product.id>
    <category:product.childSKUs>
      <category:footwear-sku repositoryId="SKU-001">
        <category:footwear-sku.colorDefault>Black</category:footwear-sku.colorDefault>
        <category:footwear-sku.sizeDefault>Large</category:footwear-sku.sizeDefault>
      </category:footwear-sku>
      <category:footwear-sku repositoryId="SKU-002">
        <category:footwear-sku.colorDefault>Black</category:footwear-sku.colorDefault>
        <category:footwear-sku.sizeDefault>Small</category:footwear-sku.sizeDefault>
      </category:footwear-sku>
      <category:footwear-sku repositoryId="SKU-003">
        <category:footwear-sku.colorDefault>Red</category:footwear-sku.colorDefault>
        <category:footwear-sku.sizeDefault>Large</category:footwear-sku.sizeDefault>
      </category:footwear-sku>
      <category:footwear-sku repositoryId="SKU-004">
        <category:footwear-sku.colorDefault>Red</category:footwear-sku.colorDefault>
        <category:footwear-sku.sizeDefault>Small</category:footwear-sku.sizeDefault>
      </category:footwear-sku>
    </category:product.childSKUs>
  </category:product>
</category:category.fixedChildProducts>
于 2013-04-19T06:00:57.490 回答