【问题标题】:Merging child nodes of an XML file based on element IDs基于元素 ID 合并 XML 文件的子节点
【发布时间】:2013-04-19 03:12:02
【问题描述】:

我正在尝试根据元素 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 属性,并将具有相同产品repositoryId 的所有childSKUs 组合在一起。每个产品节点都应该有一个唯一的repositoryId。请帮忙。

【问题讨论】:

    标签: xml xslt merge


    【解决方案1】:

    这是一个使用 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>
    

    【讨论】:

      猜你喜欢
      • 2021-05-28
      • 1970-01-01
      • 1970-01-01
      • 2020-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多