Struggling with an xslt transformation.
I have two (or more) identical <A_OutbDeliveryHeader> nodes, except for the <to_DeliveryDocumentItem> part.
<to_DeliveryDocumentItem>
<A_OutbDeliveryItemType>
...
</A_OutbDeliveryItemType>
</to_DeliveryDocumentItem>
As a result, I would like have one single <A_OutbDeliveryHeader> node, with multiple entries in <to_DeliveryDocumentItem>.
<A_OutbDeliveryHeader>
<A_OutbDeliveryHeaderType>
<DeliveryDocumentType>LF</DeliveryDocumentType>
<to_DeliveryDocumentText>
...
</to_DeliveryDocumentText>
...
<to_DeliveryDocumentItem>
<A_OutbDeliveryItemType>
...
</A_OutbDeliveryItemType>
<A_OutbDeliveryItemType>
...
</A_OutbDeliveryItemType>
</to_DeliveryDocumentItem>
</A_OutbDeliveryHeaderType>
</A_OutbDeliveryHeader>
What would be the best way to get started? Group-by? I don't have any keys though. Note : I can use XSLT 2.0 or 3.0.
Complete example XML
<?xml version="1.0" encoding="UTF-8"?>
<A_OutbDeliveryHeader>
<A_OutbDeliveryHeaderType>
<DeliveryDocumentType>LF</DeliveryDocumentType>
<to_DeliveryDocumentText>
<A_OutbDeliveryHeaderTextType>
<DeliveryDocument>800005120</DeliveryDocument>
<TextElementText>Lorem Ipsum</TextElementText>
</A_OutbDeliveryHeaderTextType>
</to_DeliveryDocumentText>
<to_DeliveryDocumentItem>
<A_OutbDeliveryItemType>
<DeliveryDocumentItem>000010</DeliveryDocumentItem>
<Warehouse>103</Warehouse>
<ItemWeightUnit>KG</ItemWeightUnit>
<ActualDeliveryQuantity>3.000</ActualDeliveryQuantity>
<ReferenceSDDocumentItem>000010</ReferenceSDDocumentItem>
<Plant>1003</Plant>
</A_OutbDeliveryItemType>
</to_DeliveryDocumentItem>
</A_OutbDeliveryHeaderType>
<A_OutbDeliveryHeaderType>
<DeliveryDocumentType>LF</DeliveryDocumentType>
<to_DeliveryDocumentText>
<A_OutbDeliveryHeaderTextType>
<DeliveryDocument>800005120</DeliveryDocument>
<TextElementText>Lorem Ipsum</TextElementText>
</A_OutbDeliveryHeaderTextType>
</to_DeliveryDocumentText>
<to_DeliveryDocumentItem>
<A_OutbDeliveryItemType>
<DeliveryDocumentItem>000011</DeliveryDocumentItem>
<Warehouse>104</Warehouse>
<ItemWeightUnit>PC</ItemWeightUnit>
<ActualDeliveryQuantity>1.000</ActualDeliveryQuantity>
<ReferenceSDDocument>4858</ReferenceSDDocument>
</A_OutbDeliveryItemType>
</to_DeliveryDocumentItem>
</A_OutbDeliveryHeaderType>
</A_OutbDeliveryHeader>
Edit : my XSLT (I can use XSLT 2.0 or 3.0) so far, seems to do the trick.
<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="//A_OutbDeliveryHeader">
<xsl:copy>
<xsl:for-each-group select="A_OutbDeliveryHeaderType" group-by="''">
<xsl:apply-templates select="@* | node()[not(self::to_DeliveryDocumentItem)]" />
<to_DeliveryDocumentItem>
<xsl:apply-templates select="current-group()/to_DeliveryDocumentItem/A_OutbDeliveryItemType" />
</to_DeliveryDocumentItem>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
CodePudding user response:
It appears you don't need grouping, just
<xsl:template match="A_OutbDeliveryHeader">
<xsl:copy>
<xsl:copy-of select="A_OutbDeliveryHeaderType[1]/(* except to_DeliveryDocumentItem)"/>
<to_DeliveryDocumentItem>
<xsl:copy-of select="A_OutbDeliveryHeaderType/to_DeliveryDocumentItem/A_OutbDeliveryItemType"/>
</to_DeliveryDocumentItem>
</xsl:copy>
</xsl:template>