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

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

相关内容

  • 没有找到相关文章

最新更新