juls_pro_37: xslt. 1.0 Segment zusammenführen

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

  1. Hier mal mein Versuch. -> aktuell 2 offene Punkte:

    • die Position "ForwarderReferenceNumber" muss hintereinander ausgegeben werden.
    • der Inhalt von "ForwarderReferenceNumber" ist falsch.
    <xsl:key name="ForwarderReferenceNumberKey" match="Set_Item" use="GTIN" />
        
    <xsl:template match="Set_Item[position() &gt; 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> 
    
    1. 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>