juls_pro_37: XSLT 1.0 neuen Knoten mit Unterpunkte erstellen

Hi,

benötige eine Prüfung ob unter "Item" der Unterpunkt "ItemDeliveryInformation" existiert.

Wenn nein, soll dieser mit weiteren Unterpunkten erstellt werden.

LineNumDeliveryNote = 0

PackingSlipId = HeaderInformation/InvoiceNumber

DeliveryDate = HeaderInformation/InvoiceDate

DeliveredQuantity = von der entsprechenden Item die TotalQuantity

XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<SALESINVOICE>
    <HeaderInformation>		
		<InvoiceDate>20200615</InvoiceDate>
		<InvoiceNumber>201023815</InvoiceNumber>
	</HeaderInformation>		
	<LineInformation>
		<Item>
			<LineNum>1</LineNum>
			<TotalQuantity>920.00</TotalQuantity>
		</Item>
	</LineInformation>
	<LineInformation>
		<Item>
			<LineNum>2</LineNum>
			<TotalQuantity>23.00</TotalQuantity>
			<ItemDeliveryInformation>
				<LineNumDeliveryNote>0</LineNumDeliveryNote>
				<DeliveryDate>20200615</DeliveryDate>
				<DeliveredQuantity>23.00</DeliveredQuantity>
			</ItemDeliveryInformation>
		</Item>
	</LineInformation>
</SALESINVOICE>

XSLT:

    <xsl:template match="Item">
        <xsl:copy-of select="."/>
            <xsl:if test="not(ItemDeliveryInformation)">
                <ItemDeliveryInformation>
                    <LineNumDeliveryNote>0</LineNumDeliveryNote>
                    <PackingSlipId><xsl:value-of select="/SALESINVOICE/HeaderInformation/InvoiceNumber"/></PackingSlipId>
					<DeliveryDate><xsl:value-of select="/SALESINVOICE/HeaderInformation/InvoiceDate"/></DeliveryDate>
                    <DeliveredQuantity><xsl:value-of select="hier soll die TotalQuantity der richtigen Item stehen, unterscheidet sich durch die LineNum"/></DeliveredQuantity>
                </ItemDeliveryInformation>
            </xsl:if>
    </xsl:template>

Korrekt:

<?xml version="1.0" encoding="ISO-8859-1"?>
<SALESINVOICE>
    <HeaderInformation>		
		<InvoiceDate>20200615</InvoiceDate>
		<InvoiceNumber>201023815</InvoiceNumber>
	</HeaderInformation>		
	<LineInformation>
		<Item>
			<LineNum>1</LineNum>	
			<TotalQuantity>920.00</TotalQuantity>
			<ItemDeliveryInformation>
				<LineNumDeliveryNote>0</LineNumDeliveryNote>
				<PackingSlipId>LS264694</PackingSlipId>
				<DeliveryDate>20200615</DeliveryDate>
				<DeliveredQuantity>920.00</DeliveredQuantity>
			</ItemDeliveryInformation>
		</Item>
	</LineInformation>
	<LineInformation>
		<Item>
			<LineNum>2</LineNum>
			<TotalQuantity>23.00</TotalQuantity>			
			<ItemDeliveryInformation>
				<LineNumDeliveryNote>1</LineNumDeliveryNote>
				<PackingSlipId>LS264694</PackingSlipId>
				<DeliveryDate>20200615</DeliveryDate>
				<DeliveredQuantity>23.00</DeliveredQuantity>
			</ItemDeliveryInformation>
		</Item>
	</LineInformation>
</SALESINVOICE>
  1. Hallo Julian,

    benötige eine Prüfung ob unter "Item" der Unterpunkt "ItemDeliveryInformation" existiert.

    Wenn nein, soll dieser mit weiteren Unterpunkten erstellt werden.

    LineNumDeliveryNote = 0

    PackingSlipId = HeaderInformation/InvoiceNumber

    DeliveryDate = HeaderInformation/InvoiceDate

    DeliveredQuantity = von der entsprechenden Item die TotalQuantity

    Das fängt wieder an, wild zu werden. Ich kann nur noch mutmaßen:

    <xsl:template match="Item[not(ItemDeliveryInformation)]">
      <Item>
        <xsl:copy-of select="LineNum"/>
        <xsl:copy-of select="TotalQuantity"/>
        <xsl:if test="not(ItemDeliveryInformation)">
          <ItemDeliveryInformation>
            <LineNumDeliveryNote>0</LineNumDeliveryNote>
            <PackingSlipId>
              <xsl:value-of select="/SALESINVOICE/HeaderInformation/InvoiceNumber"/>
            </PackingSlipId>
            <DeliveryDate>
              <xsl:value-of select="/SALESINVOICE/HeaderInformation/InvoiceDate"/>
            </DeliveryDate>
            <DeliveredQuantity>
              <xsl:value-of select="TotalQuantity"/>
            </DeliveredQuantity>
          </ItemDeliveryInformation>
        </xsl:if>
      </Item>
    </xsl:template>
    

    Grüße,
    Thomas

    1. Nachtrag: die xsl:if-Abfrage ist unnötig, das passiert ja schon im Item[…]-Prädikat. Also reicht:

      <xsl:template match="Item[not(ItemDeliveryInformation)]">
        <Item>
          <xsl:copy-of select="LineNum"/>
          <xsl:copy-of select="TotalQuantity"/>
          <ItemDeliveryInformation>
            <LineNumDeliveryNote>0</LineNumDeliveryNote>
            <PackingSlipId>
              <xsl:value-of select="/SALESINVOICE/HeaderInformation/InvoiceNumber"/>
            </PackingSlipId>
            <DeliveryDate>
              <xsl:value-of select="/SALESINVOICE/HeaderInformation/InvoiceDate"/>
            </DeliveryDate>
            <DeliveredQuantity>
              <xsl:value-of select="TotalQuantity"/>
            </DeliveredQuantity>
          </ItemDeliveryInformation>
        </Item>
      </xsl:template>
      

      Grüße,
      Thomas

      1. danke das funktioniert genau so wie gewünscht.

        Wie kann ich das nun vor dem "LineText" stellen?

        XML:

        <?xml version="1.0" encoding="ISO-8859-1"?>
        <SALESINVOICE>
        <HeaderInformation>
        <InvoiceDate>20200707</InvoiceDate>
        <InvoiceNumber>201028006</InvoiceNumber>
        </HeaderInformation>
        <LineInformation>
        <Item>
        <LineNum>1</LineNum>
        <CustomerPurchaseOrder>test1</CustomerPurchaseOrder>
        <TotalQuantity>33.00</TotalQuantity>
        <LineText>
        <Qualifier>INV</Qualifier>
        <Text>Text1</Text>
        </LineText>    			  
        </Item>
        </LineInformation>
        <LineInformation>
        <Item>
        <LineNum>2</LineNum>
        <CustomerPurchaseOrder>test2</CustomerPurchaseOrder>
        <TotalQuantity>55.00</TotalQuantity>
        <LineText>
        <Qualifier>INV</Qualifier>
        <Text>Text2</Text>
        </LineText>        		  
        </Item>
        </LineInformation>
        </SALESINVOICE>
        

        XSLT:

        <xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        		<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
        
        	<xsl:template match="node()|@*" name="identity">
        		<xsl:copy>
        			<xsl:apply-templates select="node()|@*"/>
        		</xsl:copy>
        	</xsl:template>
            
                <!-- Erstellt den Knoten ItemDeliveryInformation (mit Unterpunkten) wenn dier fehlt -->
            <xsl:template match="Item[not(ItemDeliveryInformation)]"> 
            <xsl:apply-templates select="node()"/>
                  <Item>        
                    <ItemDeliveryInformation>            
                      <LineNumDeliveryNote>0</LineNumDeliveryNote>
                      <PackingSlipId>
                        <xsl:value-of select="/SALESINVOICE/HeaderInformation/InvoiceNumber"/>
                      </PackingSlipId>
                      <DeliveryDate>
                        <xsl:value-of select="/SALESINVOICE/HeaderInformation/InvoiceDate"/>
                      </DeliveryDate>
                      <DeliveredQuantity>
                        <xsl:value-of select="TotalQuantity"/>
                      </DeliveredQuantity>
                    </ItemDeliveryInformation>
                  </Item>
            </xsl:template>
        
        </xsl:stylesheet>
        

        Korrekt:

        <?xml version="1.0" encoding="UTF-8"?>
        <SALESINVOICE>
        <HeaderInformation>
        <InvoiceDate>20200707</InvoiceDate>
        <InvoiceNumber>201028006</InvoiceNumber>
        </HeaderInformation>
        <LineInformation>
        <LineNum>1</LineNum>
        <CustomerPurchaseOrder>test1</CustomerPurchaseOrder>
        <TotalQuantity>33.00</TotalQuantity>
        <ItemDeliveryInformation>
        <LineNumDeliveryNote>0</LineNumDeliveryNote>
        <PackingSlipId>201028006</PackingSlipId>
        <DeliveryDate>20200707</DeliveryDate>
        <DeliveredQuantity>33.00</DeliveredQuantity>
        </ItemDeliveryInformation>
        <LineText>
        <Qualifier>INV</Qualifier>
        <Text>Text1</Text>
        </LineText>    			  
        <Item>
        </Item>
        </LineInformation>
        <LineInformation>
        <LineNum>2</LineNum>
        <CustomerPurchaseOrder>test2</CustomerPurchaseOrder>
        <TotalQuantity>55.00</TotalQuantity>
        <ItemDeliveryInformation>
        <LineNumDeliveryNote>0</LineNumDeliveryNote>
        <PackingSlipId>201028006</PackingSlipId>
        <DeliveryDate>20200707</DeliveryDate>
        <DeliveredQuantity>55.00</DeliveredQuantity>
        </ItemDeliveryInformation>
        <LineText>
        <Qualifier>INV</Qualifier>
        <Text>Text2</Text>
        </LineText>        		  
        <Item>
        </Item>
        </LineInformation>
        </SALESINVOICE>
        
        1. Hallo Julian,

          Wie kann ich das nun vor dem "LineText" stellen?

          Du kommst mit isolierten Problemen, die dann weitere nach sich ziehen. Jetzt sollen da leere Item-Elemente rausfallen? Probiere mal selbst weiter.

          Grüße,
          Thomas

          1. Hallo Thomas,

            das verstehe ich nicht, warum sollen leere Werte rausfallen?

            Habe im XML Anfangs übersehen, dass es einen Knoten "LineText" dazwischen geben könnte. Und der Knoten "ItemDeliveryInformation" müsste vor "LineText" stehen, falls dieser vorhanden ist.

            Wenn der Knoten "ItemDeliveryInformation" an der falschen Stelle steht, hat mein Konverter im Nachgang Probleme.

            LG

            1. Hallo Julian,

              das verstehe ich nicht, warum sollen leere Werte rausfallen?

              Weil unter "korrekt" steht: <Item></Item>.

              Es ist somit auch für mich nicht so einfach, das konkrete Ziel zu erkennen.

              Grüße,
              Thomas

        2. Hätte dies vorgeschlagen:

          
            <xsl:template match="LineText" />
          
              
                  
              <xsl:template match="Item[not(ItemDeliveryInformation)]">
                  <xsl:copy>
          			<xsl:apply-templates select="node() | @*" />
                      <ItemDeliveryInformation>            
                        <LineNumDeliveryNote>0</LineNumDeliveryNote>
                        <PackingSlipId>
                          <xsl:value-of select="/SALESINVOICE/HeaderInformation/InvoiceNumber"/>
                        </PackingSlipId>
                        <DeliveryDate>
                          <xsl:value-of select="/SALESINVOICE/HeaderInformation/InvoiceDate"/>
                        </DeliveryDate>
                        <DeliveredQuantity>
                          <xsl:value-of select="TotalQuantity"/>
                        </DeliveredQuantity>
                      </ItemDeliveryInformation>    
                      <xsl:copy-of select="LineText"/>
                   </xsl:copy>    	
              </xsl:template>
          
          1. Hallo Julian,

            Hätte dies vorgeschlagen:

            
              <xsl:template match="LineText" />
            

            Das schließt LineText aus dem Ergebnis aus. Soweit waren wir doch schon bei Identity-Transformationen + zusätzlichen Anpassungen.

            In einem Ansatz sollte ItemDeliveryInformation neu erzeugt werden. Nun soll dieses neue Element, aber auch ein bereits vorhandenes Element vor LineText erscheinen. Das sind alles Versatzstücke, die sich nicht einfach kombinieren lassen.

            Ein konretes Vorher-/Nachher-Beispiel würde ich mir noch anschauen, aber mühsam Dinge zu bearbeiten, die dann wieder unnütz sind, muss ich auch nicht haben (so sehr ich XSLT auch mag ;).

            Grüße,
            Thomas

            1. Hi, ach das war mein Fehler. Hatte ich total übersehen und in meinem File falsch angeführt, das mit dem Item.

              Ich habe es so gelöst und komme auf das gewünschte Ergebnis, aber es gibt sicher wieder einen leichteren Weg... :)

              XML:

              <?xml version="1.0" encoding="ISO-8859-1"?>
              <SALESINVOICE>
              <HeaderInformation>
              <InvoiceDate>20200707</InvoiceDate>
              <InvoiceNumber>201028006</InvoiceNumber>
              </HeaderInformation>
              <LineInformation>
              <Item>
              <LineNum>1</LineNum>
              <CustomerPurchaseOrder>test1</CustomerPurchaseOrder>
              <TotalQuantity>33.00</TotalQuantity>
              <LineText>
              <Qualifier>INV</Qualifier>
              <Text>Text1</Text>
              </LineText>        		  
              </Item>
              </LineInformation>
              <LineInformation>
              <Item>
              <LineNum>2</LineNum>
              <CustomerPurchaseOrder>test2</CustomerPurchaseOrder>
              <TotalQuantity>55.00</TotalQuantity>
              <LineText>
              <Qualifier>INV</Qualifier>
              <Text>Text2</Text>
              </LineText>        		  
              </Item>
              </LineInformation>
              </SALESINVOICE>
              

              XSLT:

                   <!--delete LineText-->
                <xsl:template match="LineText" />
                
              	<!-- Erstellt den Knoten ItemDeliveryInformation (mit Unterpunkten) wenn dieser fehlt -->
                  <xsl:template match="Item[not(ItemDeliveryInformation)]">
                      <xsl:copy>
              			<xsl:apply-templates select="node() | @*" />
                          <ItemDeliveryInformation>            
                            <LineNumDeliveryNote>0</LineNumDeliveryNote>
                            <PackingSlipId>
                              <xsl:value-of select="CustomerPurchaseOrder"/>
                            </PackingSlipId>
                            <DeliveryDate>
                              <xsl:value-of select="/SALESINVOICE/HeaderInformation/InvoiceDate"/>
                            </DeliveryDate>
                            <DeliveredQuantity>
                              <xsl:value-of select="TotalQuantity[. != 0.00]"/>
              				<xsl:value-of select="TotalQuantity_Nachverrechnung[. != 0.00]"/>
                            </DeliveredQuantity>
                          </ItemDeliveryInformation>    
                          <xsl:copy-of select="LineText"/>
                       </xsl:copy>    	
                  </xsl:template> 
              

              Korrekt:

              <?xml version="1.0" encoding="UTF-8"?>
              <SALESINVOICE>
                 <HeaderInformation>
                    <InvoiceDate>20200707</InvoiceDate>
                    <InvoiceNumber>201028006</InvoiceNumber>
                 </HeaderInformation>
                 <LineInformation>
                    <Item>
                       <LineNum>1</LineNum>
                       <CustomerPurchaseOrder>test1</CustomerPurchaseOrder>
                       <TotalQuantity>33.00</TotalQuantity>  
                       <ItemDeliveryInformation>
                          <LineNumDeliveryNote>0</LineNumDeliveryNote>
                          <PackingSlipId>test1</PackingSlipId>
                          <DeliveryDate>20200707</DeliveryDate>
                          <DeliveredQuantity>33.00</DeliveredQuantity>
                       </ItemDeliveryInformation>
                       <LineText>
                          <Qualifier>INV</Qualifier>
                          <Text>Text1</Text>
                       </LineText>
                    </Item>
                 </LineInformation>
                 <LineInformation>
                    <Item>
                       <LineNum>2</LineNum>
                       <CustomerPurchaseOrder>test2</CustomerPurchaseOrder>
                       <TotalQuantity>55.00</TotalQuantity>
                       <ItemDeliveryInformation>
                          <LineNumDeliveryNote>0</LineNumDeliveryNote>
                          <PackingSlipId>test2</PackingSlipId>
                          <DeliveryDate>20200707</DeliveryDate>
                          <DeliveredQuantity>55.00</DeliveredQuantity>
                       </ItemDeliveryInformation>
                       <LineText>
                          <Qualifier>INV</Qualifier>
                          <Text>Text2</Text>
                       </LineText>
                    </Item>
                 </LineInformation>
              </SALESINVOICE>