Вы можете сделать это, переопределив стандартное преобразование идентичности дополнительными шаблонами для особых случаев.
Во-первых, когда вы соответствуете узлу TraceRequest , вы хотите сразу перейти к соответствующим узлам TraceItem , где вы будете выполнять копирование. В этом случае текущий узел TraceRequest может быть передан в качестве параметра для последующего копирования его детей.
<xsl:template match="TraceRequest">
<xsl:apply-templates select="TraceItems/TraceItem">
<xsl:with-param name="TraceRequestNode" select="."/>
</xsl:apply-templates>
</xsl:template>
Затем при сопоставлении TraceItem можно просто скопировать дочерние элементы TraceRequest , переданные через параметр (исключая узел TraceItems ), а также дочерние элементы узла TraceItem , на котором вы сейчас находитесь.
<xsl:template match="TraceItem">
<xsl:param name="TraceRequestNode"/>
<TraceRequest>
<xsl:apply-templates select="$TraceRequestNode/*[not(self::TraceItems)]"/>
<xsl:apply-templates select="@*|node()"/>
</TraceRequest>
</xsl:template>
Итак, учитывая полный XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="TraceRequest">
<xsl:apply-templates select="TraceItems/TraceItem">
<xsl:with-param name="TraceRequestNode" select="."/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="TraceItem">
<xsl:param name="TraceRequestNode"/>
<TraceRequest>
<xsl:apply-templates select="$TraceRequestNode/*[not(self::TraceItems)]"/>
<xsl:apply-templates select="@*|node()"/>
</TraceRequest>
</xsl:template>
</xsl:stylesheet>
При применении к вашему образцу XML вывод будет следующим:
<TransactionRequest>
<OrderRequests>
<OrderRequest>
<ReferenceNumber>1234567</ReferenceNumber>
<TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime>
<IsRush>true</IsRush>
<ShippingAddress>
<Name>Tom Hanks</Name>
<Address1>1123 Canada Way</Address1>
<City>Burnaby</City>
<Province>BC</Province>
<PostalCode>V3B13B</PostalCode>
<HomePhone>6048871121</HomePhone>
<BusinessPhone>6041232342</BusinessPhone>
</ShippingAddress>
<ProgramType>C2</ProgramType>
<Comments>Deliver to the receptionist</Comments>
<Items>
<Item>
<Sku>UN10004</Sku>
<Quantity>2</Quantity>
</Item>
<Item>
<Sku>UN980011</Sku>
<Quantity>1</Quantity>
</Item>
</Items>
</OrderRequest>
</OrderRequests>
<TraceRequests>
<TraceRequest>
<ReferenceNumber>23432345</ReferenceNumber>
<TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime>
<OriginalReferenceNumber>1234567</OriginalReferenceNumber>
<Comments>Trace Items</Comments>
<Sku>UN10004</Sku>
<Quantity>2</Quantity>
<ShipmentNumber>CM88888990</ShipmentNumber>
</TraceRequest>
<TraceRequest>
<ReferenceNumber>23432345</ReferenceNumber>
<TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime>
<OriginalReferenceNumber>1234567</OriginalReferenceNumber>
<Comments>Trace Items</Comments>
<Sku>UN980011</Sku>
<ProductCode>AA0091</ProductCode>
<Quantity>1</Quantity>
<ShipmentNumber>DDP123123123</ShipmentNumber>
</TraceRequest>
</TraceRequests>
</TransactionRequest>