使用 XSLT 合并

Merging using XSLT

以下是我的输入XML。这里每个 X_DLV_TAB_ITEM 有多个 RL_DETAILS,它们又有多个 RL_DETAILS_ITEM。每个 X_DLV_TAB_ITEM 包含 TYPE。

我的要求是,如果两个或多个 X_DLV_TAB_ITEM 的 TYPE 相同,则只应创建一个 X_DLV_TAB_ITEM,它将包含具有相同 TYPE 的所有 RL_DETAILS_ITEM不同的TYPE需要跟随其余的。

输入:

<X_DLV_TAB>
    <X_DLV_TAB_ITEM>
        <TYPE>A</TYPE>
        <TRANSACTION_CODE>RC</TRANSACTION_CODE>
        <DELIVERY_ID>46689764</DELIVERY_ID>
        <NAME>46689764</NAME>
        <RL_DETAILS>
            <RL_DETAILS_ITEM>
                <DELIVERY_DETAIL_ID>14460996</DELIVERY_DETAIL_ID>
                <GROSS_WEIGHT>11</GROSS_WEIGHT>
                <WEIGHT_UOM_CODE>LB</WEIGHT_UOM_CODE>
                <VOLUME>0.2</VOLUME>
                <VOLUME_UOM_CODE>CF</VOLUME_UOM_CODE>
                <REQUESTED_QUANTITY>5</REQUESTED_QUANTITY>
            </RL_DETAILS_ITEM>
            <RL_DETAILS_ITEM>
                <DELIVERY_DETAIL_ID>14460997</DELIVERY_DETAIL_ID>
                <GROSS_WEIGHT>5.28333</GROSS_WEIGHT>
                <WEIGHT_UOM_CODE>LB</WEIGHT_UOM_CODE>
                <VOLUME>0.12</VOLUME>
                <VOLUME_UOM_CODE>CF</VOLUME_UOM_CODE>
                <REQUESTED_QUANTITY>3</REQUESTED_QUANTITY>
            </RL_DETAILS_ITEM>
        </RL_DETAILS>
    </X_DLV_TAB_ITEM>
    <X_DLV_TAB_ITEM>
        <TYPE>A</TYPE>
        <TRANSACTION_CODE>RC</TRANSACTION_CODE>
        <DELIVERY_ID>46689764</DELIVERY_ID>
        <NAME>46689764</NAME>
        <RL_DETAILS>
            <RL_DETAILS_ITEM>
                <DELIVERY_DETAIL_ID>14460993</DELIVERY_DETAIL_ID>
                <GROSS_WEIGHT>17.6111</GROSS_WEIGHT>
                <WEIGHT_UOM_CODE>LB</WEIGHT_UOM_CODE>
                <VOLUME>0.4</VOLUME>
                <VOLUME_UOM_CODE>CF</VOLUME_UOM_CODE>
                <REQUESTED_QUANTITY>12</REQUESTED_QUANTITY>
            </RL_DETAILS_ITEM>
            <RL_DETAILS_ITEM>
                <DELIVERY_DETAIL_ID>14460994</DELIVERY_DETAIL_ID>
                <GROSS_WEIGHT>33</GROSS_WEIGHT>
                <WEIGHT_UOM_CODE>LB</WEIGHT_UOM_CODE>
                <VOLUME>0.6</VOLUME>
                <VOLUME_UOM_CODE>CF</VOLUME_UOM_CODE>
                <REQUESTED_QUANTITY>15</REQUESTED_QUANTITY>
            </RL_DETAILS_ITEM>
            <RL_DETAILS_ITEM>
                <DELIVERY_DETAIL_ID>14460995</DELIVERY_DETAIL_ID>
                <GROSS_WEIGHT>26.4</GROSS_WEIGHT>
                <WEIGHT_UOM_CODE>LB</WEIGHT_UOM_CODE>
                <VOLUME>0.48</VOLUME>
                <VOLUME_UOM_CODE>CF</VOLUME_UOM_CODE>
                <REQUESTED_QUANTITY>10</REQUESTED_QUANTITY>
            </RL_DETAILS_ITEM>
        </RL_DETAILS>
    </X_DLV_TAB_ITEM>
    <X_DLV_TAB_ITEM>
        <TYPE>B</TYPE>
        <TRANSACTION_CODE>RC</TRANSACTION_CODE>
        <DELIVERY_ID>46689766</DELIVERY_ID>
        <NAME>46689766</NAME>
        <RL_DETAILS>
            <RL_DETAILS_ITEM>
                <DELIVERY_DETAIL_ID>14460993</DELIVERY_DETAIL_ID>
                <GROSS_WEIGHT>17.6111</GROSS_WEIGHT>
                <WEIGHT_UOM_CODE>LB</WEIGHT_UOM_CODE>
                <VOLUME>0.4</VOLUME>
                <VOLUME_UOM_CODE>CF</VOLUME_UOM_CODE>
                <REQUESTED_QUANTITY>10</REQUESTED_QUANTITY>
            </RL_DETAILS_ITEM>
        </RL_DETAILS>
    </X_DLV_TAB_ITEM>
    <X_DLV_TAB_ITEM>
        <TYPE>C</TYPE>
        <TRANSACTION_CODE>RC</TRANSACTION_CODE>
        <DELIVERY_ID>46689767</DELIVERY_ID>
        <NAME>46689767</NAME>
        <RL_DETAILS>
            <RL_DETAILS_ITEM>
                <DELIVERY_DETAIL_ID>14460995</DELIVERY_DETAIL_ID>
                <GROSS_WEIGHT>26.4</GROSS_WEIGHT>
                <WEIGHT_UOM_CODE>LB</WEIGHT_UOM_CODE>
                <VOLUME>0.48</VOLUME>
                <VOLUME_UOM_CODE>CF</VOLUME_UOM_CODE>
                <REQUESTED_QUANTITY>150</REQUESTED_QUANTITY>
            </RL_DETAILS_ITEM>
        </RL_DETAILS>
    </X_DLV_TAB_ITEM>
</X_DLV_TAB>

输出:

<X_DLV_TAB>
    <X_DLV_TAB_ITEM>
        <TYPE>A</TYPE>
        <TRANSACTION_CODE>RC</TRANSACTION_CODE>
        <DELIVERY_ID>46689764</DELIVERY_ID>
        <NAME>46689764</NAME>
        <RL_DETAILS>
            <RL_DETAILS_ITEM>
                <DELIVERY_DETAIL_ID>14460996</DELIVERY_DETAIL_ID>
                <GROSS_WEIGHT>11</GROSS_WEIGHT>
                <WEIGHT_UOM_CODE>LB</WEIGHT_UOM_CODE>
                <VOLUME>0.2</VOLUME>
                <VOLUME_UOM_CODE>CF</VOLUME_UOM_CODE>
                <REQUESTED_QUANTITY>5</REQUESTED_QUANTITY>
            </RL_DETAILS_ITEM>
            <RL_DETAILS_ITEM>
                <DELIVERY_DETAIL_ID>14460997</DELIVERY_DETAIL_ID>
                <GROSS_WEIGHT>5.28333</GROSS_WEIGHT>
                <WEIGHT_UOM_CODE>LB</WEIGHT_UOM_CODE>
                <VOLUME>0.12</VOLUME>
                <VOLUME_UOM_CODE>CF</VOLUME_UOM_CODE>
                <REQUESTED_QUANTITY>3</REQUESTED_QUANTITY>
            </RL_DETAILS_ITEM>
            <RL_DETAILS_ITEM>
                <DELIVERY_DETAIL_ID>14460993</DELIVERY_DETAIL_ID>
                <GROSS_WEIGHT>17.6111</GROSS_WEIGHT>
                <WEIGHT_UOM_CODE>LB</WEIGHT_UOM_CODE>
                <VOLUME>0.4</VOLUME>
                <VOLUME_UOM_CODE>CF</VOLUME_UOM_CODE>
                <REQUESTED_QUANTITY>10</REQUESTED_QUANTITY>
            </RL_DETAILS_ITEM>
            <RL_DETAILS_ITEM>
                <DELIVERY_DETAIL_ID>14460994</DELIVERY_DETAIL_ID>
                <GROSS_WEIGHT>33</GROSS_WEIGHT>
                <WEIGHT_UOM_CODE>LB</WEIGHT_UOM_CODE>
                <VOLUME>0.6</VOLUME>
                <VOLUME_UOM_CODE>CF</VOLUME_UOM_CODE>
                <REQUESTED_QUANTITY>15</REQUESTED_QUANTITY>
            </RL_DETAILS_ITEM>
            <RL_DETAILS_ITEM>
                <DELIVERY_DETAIL_ID>14460995</DELIVERY_DETAIL_ID>
                <GROSS_WEIGHT>26.4</GROSS_WEIGHT>
                <WEIGHT_UOM_CODE>LB</WEIGHT_UOM_CODE>
                <VOLUME>0.48</VOLUME>
                <VOLUME_UOM_CODE>CF</VOLUME_UOM_CODE>
                <REQUESTED_QUANTITY>12</REQUESTED_QUANTITY>
            </RL_DETAILS_ITEM>
        </RL_DETAILS>
    </X_DLV_TAB_ITEM>
    <X_DLV_TAB_ITEM>
        <TYPE>B</TYPE>
        <TRANSACTION_CODE>RC</TRANSACTION_CODE>
        <DELIVERY_ID>46689766</DELIVERY_ID>
        <NAME>46689766</NAME>
        <RL_DETAILS>
            <RL_DETAILS_ITEM>
                <DELIVERY_DETAIL_ID>14460993</DELIVERY_DETAIL_ID>
                <GROSS_WEIGHT>17.6111</GROSS_WEIGHT>
                <WEIGHT_UOM_CODE>LB</WEIGHT_UOM_CODE>
                <VOLUME>0.4</VOLUME>
                <VOLUME_UOM_CODE>CF</VOLUME_UOM_CODE>
                <REQUESTED_QUANTITY>10</REQUESTED_QUANTITY>
            </RL_DETAILS_ITEM>
        </RL_DETAILS>
    </X_DLV_TAB_ITEM>
    <X_DLV_TAB_ITEM>
        <TYPE>C</TYPE>
        <TRANSACTION_CODE>RC</TRANSACTION_CODE>
        <DELIVERY_ID>46689767</DELIVERY_ID>
        <NAME>46689767</NAME>
        <RL_DETAILS>
            <RL_DETAILS_ITEM>
                <DELIVERY_DETAIL_ID>14460995</DELIVERY_DETAIL_ID>
                <GROSS_WEIGHT>26.4</GROSS_WEIGHT>
                <WEIGHT_UOM_CODE>LB</WEIGHT_UOM_CODE>
                <VOLUME>0.48</VOLUME>
                <VOLUME_UOM_CODE>CF</VOLUME_UOM_CODE>
                <REQUESTED_QUANTITY>150</REQUESTED_QUANTITY>
            </RL_DETAILS_ITEM>
        </RL_DETAILS>
    </X_DLV_TAB_ITEM>
</X_DLV_TAB>

我的代码:

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


    <xsl:key name="first_of_source" match="X_DLV_TAB/X_DLV_TAB_ITEM[not(preceding-sibling::X_DLV_TAB_ITEM/TYPE = TYPE)]" use="TYPE"/>

    <xsl:key name="same_source" match="X_DLV_TAB/X_DLV_TAB_ITEM/RL_DETAILS" use="RL_DETAILS_ITEM"/>


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

    <xsl:template match="X_DLV_TAB">
        <xsl:copy>
            <xsl:apply-templates select="key('first_of_source', X_DLV_TAB_ITEM/TYPE)"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="RL_DETAILS">
        <xsl:copy>
            <xsl:apply-templates select="key('same_source', RL_DETAILS_ITEM)/RL_DETAILS_ITEM"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

并且此代码未生成所需的输出。我正在使用 XSLT 1.0。

AFAICT,你想做的事:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="item-by-type" match="X_DLV_TAB_ITEM" use="TYPE"/>

<xsl:template match="/X_DLV_TAB">
    <xsl:copy>
        <!-- create a group for each distinct TYPE -->
        <xsl:for-each select="X_DLV_TAB_ITEM[count(. | key('item-by-type', TYPE)[1]) = 1]">
            <xsl:copy>
                <!-- copy common elements -->
                <xsl:copy-of select="*[not(self::RL_DETAILS)]"/>
                <RL_DETAILS>
                    <!-- copy all RL_DETAILS_ITEMs of current group-->
                    <xsl:copy-of select="key('item-by-type', TYPE)/RL_DETAILS/RL_DETAILS_ITEM"/>
                </RL_DETAILS>
            </xsl:copy>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

请注意,这里假设所有具有相同 TYPEX_DLV_TAB_ITEM 具有相同的数据,但 RL_DETAILS 的内容除外。因此,除了RL_DETAILS的内容之外的所有数据都是从每组的第一个X_DLV_TAB_ITEM开始复制的。然后 RL_DETAILS 元素由整个组的 RL_DETAILS_ITEM 填充。