xslt. 1.0 Segment zusammenführen
juls_pro_37
- xml
- xsl
Hi,
bitte um Hilfe.
In meinem Fall muss ein Knoten (Set_Item.ForwarderReferenceNumber) auf einen (falls vorhanden) identen Artikel kopiert werden und anschließend gelöscht werden.
Konkret: Set_Item.GTIN (555) ist das Kriterium (somit erkennt man den doppelten Artikel) hat jedoch eine unterschiedliche "ForwarderReferenceNumber".
Somit soll die ForwarderReferenceNumber von Set_Item.LineNum 7 auf Set_Item.LineNum 2 kopiert werden und anschließend der gesamte Knoten Set_Item (wo die LineNum 7) gelöscht werden.
Aktuell:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<OSTRPT>
<Interchange>
<Recipient>1</Recipient>
<Sender>2</Sender>
</Interchange>
<HeaderInformation>
<AcknowledgeId>3</AcknowledgeId>
</HeaderInformation>
<LineInformation>
<Item>
<LineNum>3</LineNum>
<GTIN>123</GTIN>
<Quantity>1.00</Quantity>
<MeasureUnit>PCE</MeasureUnit>
<DeliveryDate>2024-03-13</DeliveryDate>
<Status>24</Status>
<ForwarderReferenceNumber>00000</ForwarderReferenceNumber>
<Date>1</Date>
</Item>
<Set_Item>
<LineNum>4</LineNum>
<GTIN>456</GTIN>
<Quantity>1.00</Quantity>
<MeasureUnit>PCE</MeasureUnit>
<DeliveryDate>2024-03-13</DeliveryDate>
<Status>24</Status>
<ForwarderReferenceNumber>11111</ForwarderReferenceNumber>
<Date>1</Date>
</Set_Item>
<Set_Item>
<LineNum>2</LineNum>
<GTIN>555</GTIN>
<Quantity>1.00</Quantity>
<MeasureUnit>PCE</MeasureUnit>
<DeliveryDate>2024-03-13</DeliveryDate>
<Status>24</Status>
<ForwarderReferenceNumber>666</ForwarderReferenceNumber>
<Date>2</Date>
</Set_Item>
<Set_Item>
<LineNum>7</LineNum>
<GTIN>555</GTIN>
<Quantity>1.00</Quantity>
<MeasureUnit>PCE</MeasureUnit>
<DeliveryDate>2024-03-13</DeliveryDate>
<Status>24</Status>
<ForwarderReferenceNumber>777</ForwarderReferenceNumber>
<Date>3</Date>
</Set_Item>
</LineInformation>
</OSTRPT>
Korrekt:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<OSTRPT>
<Interchange>
<Recipient>1</Recipient>
<Sender>2</Sender>
</Interchange>
<HeaderInformation>
<AcknowledgeId>3</AcknowledgeId>
</HeaderInformation>
<LineInformation>
<Item>
<LineNum>3</LineNum>
<GTIN>123</GTIN>
<Quantity>1.00</Quantity>
<MeasureUnit>PCE</MeasureUnit>
<DeliveryDate>2024-03-13</DeliveryDate>
<Status>24</Status>
<ForwarderReferenceNumber>00000</ForwarderReferenceNumber>
<Date>1</Date>
</Item>
<Set_Item>
<LineNum>4</LineNum>
<GTIN>456</GTIN>
<Quantity>1.00</Quantity>
<MeasureUnit>PCE</MeasureUnit>
<DeliveryDate>2024-03-13</DeliveryDate>
<Status>24</Status>
<ForwarderReferenceNumber>11111</ForwarderReferenceNumber>
<Date>1</Date>
</Set_Item>
<Set_Item>
<LineNum>2</LineNum>
<GTIN>555</GTIN>
<Quantity>1.00</Quantity>
<MeasureUnit>PCE</MeasureUnit>
<DeliveryDate>2024-03-13</DeliveryDate>
<Status>24</Status>
<ForwarderReferenceNumber>666</ForwarderReferenceNumber>
<ForwarderReferenceNumber>777</ForwarderReferenceNumber>
<Date>2</Date>
</Set_Item>
</LineInformation>
</OSTRPT>
mein XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:choose>
<xsl:when test="//LineInformation[not(Item)] and //LineInformation[not(Set_Item)]"></xsl:when>
<xsl:when test="not(//Set_Item) and not(//Item)"></xsl:when>
<xsl:when test="//CustomerPurchaseOrder [contains(., '#')]"></xsl:when>
<xsl:otherwise> <xsl:apply-templates select="@* | node()"/></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:key name="item" match="Item" use="concat(LineNum, '|', GTIN, '|', SupplierArticleNumber, '|', Quantity)"/>
<xsl:key name="set_item" match="Set_Item" use="concat(LineNum, '|', GTIN, '|', SupplierArticleNumber, '|', ForwarderReferenceNumber)"/>
<!-- Identity-Template für die nicht explizit benannten Elemente -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Set_Item">
<xsl:element name="Item">
<!--copy all other nodes-->
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="Item[generate-id() != generate-id(key('item', concat(LineNum, '|', GTIN, '|', SupplierArticleNumber, '|', Quantity))[1])]" />
<xsl:template match="Set_Item[generate-id() != generate-id(key('set_item', concat(LineNum, '|', GTIN, '|', SupplierArticleNumber, '|', ForwarderReferenceNumber))[1])]" />
<!-- delete empty nodes -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(@*|*|comment()|processing-instruction()) and normalize-space()='']"/>
</xsl:stylesheet>
Danke & LG Julian
Hier mal mein Versuch. -> aktuell 2 offene Punkte:
<xsl:key name="ForwarderReferenceNumberKey" match="Set_Item" use="GTIN" />
<xsl:template match="Set_Item[position() > 1]" />
<xsl:template match="Set_Item[following-sibling::*[1]][generate-id() = generate-id(key('ForwarderReferenceNumberKey',GTIN)[1])]">
<Set_Item>
<xsl:apply-templates select="@* | node()"/>
<ForwarderReferenceNumber>
<xsl:value-of select="normalize-space(ForwarderReferenceNumber)" />
</ForwarderReferenceNumber>
</Set_Item>
</xsl:template>
Hier die Lösung:
<xsl:key name="gtin-group" match="Set_Item" use="GTIN"/>
<xsl:key name="gtin-ref-group" match="Set_Item" use="concat(GTIN, '|', ForwarderReferenceNumber)"/>
<xsl:template match="Set_Item[not(generate-id() = generate-id(key('gtin-group', GTIN)[1]))]"/>
<xsl:template match="ForwarderReferenceNumber">
<xsl:copy-of select=". | key('gtin-group', ../GTIN)[generate-id() = generate-id(key('gtin-ref-group', concat(GTIN, '|', ForwarderReferenceNumber))[1])]/ForwarderReferenceNumber"/>
</xsl:template>