juls_pro_37
juls_pro_37

Reputation: 79

XSLT 1.0 if condition

can you help me please?

If there are differents at "PackingslipId"-"LineInformation"-"Lines" i don´t like to have "PackingslipId" and "DeliveryDate" on "HeaderInformation".

If the "PackingslipId" is always the same at "LineInformation"-"Item" than on "HeaderInformation" the output "PackingslipId" and "DeliveryDate" is ok.

Please note: (I don´t no if important; it also can be, that there is just one Article ("LineInformation"-"Item" - with "OrderLineNum" 1) - in this case, the "PackingslipId" is the same of "Item" and "HeaderInformation" so "PackingslipId" and "DeliveryDate" should be also on "HeaderInformation" and "LineItem"

My XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<SALESINVOICE>
	<Interchange>
		<Recipient></Recipient>
		<Sender></Sender>
		<CreationDate></CreationDate>
		<Test></Test>
		<Interchange_Control_Number></Interchange_Control_Number>
	</Interchange>
	<HeaderInformation>
		<OrigInvoiceNumber>1</OrigInvoiceNumber>
		<InvoiceType>INVOIC</InvoiceType>
		<InvoiceDate>2019.01.23</InvoiceDate>
		<InvoiceNumber></InvoiceNumber>
		<PurchOrderReference>fddf</PurchOrderReference>
		<SalesOrderReference></SalesOrderReference>
		<CustomerOrderReference>fdgfdg</CustomerOrderReference>
		<PackingslipId>1079304</PackingslipId>
		<DeliveryDate>2019.01.23</DeliveryDate>
		<Currency></Currency>
		<WeightAndVolume />
		<DeliveryAddressInformation>
			<Name></Name>
			<Street></Street>
			<ZipCode></ZipCode>
			<City></City>
			<Country></Country>
		</DeliveryAddressInformation>
		<InvoiceAddressInformation>
			<GLN></GLN>
			<Name></Name>
			<Street></Street>
			<ZipCode></ZipCode>
			<City></City>
			<Country></Country>
			<VATNum></VATNum>
			<InternalNumber></InternalNumber>
		</InvoiceAddressInformation>
		<BuyerAddressInformation />
		<SupplierAddressInformation>
			<GLN></GLN>
			<Name></Name>
			<Street></Street>
			<ZipCode></ZipCode>
			<City></City>
			<Country></Country>
			<VATNum></VATNum>
			<Contact />
		</SupplierAddressInformation>
	</HeaderInformation>
	<LineInformation>
		<Item>
			<OrderLineNum>1</OrderLineNum>
			<GTIN></GTIN>
			<GTINDescription></GTINDescription>
			<PackingslipId>1079304</PackingslipId>
			<DeliveryDate>2019.01.23</DeliveryDate>
			<SupplierArticleNumber></SupplierArticleNumber>
			<Quantity>1</Quantity>
			<DeliveredQuantity>1</DeliveredQuantity>
		</Item>
	</LineInformation>
	<LineInformation>
		<Item>
			<OrderLineNum>2</OrderLineNum>
			<GTIN></GTIN>
			<GTINDescription></GTINDescription>
			<PackingslipId>1079305</PackingslipId>
			<DeliveryDate>2019.01.23</DeliveryDate>
			<SupplierArticleNumber></SupplierArticleNumber>
			<Quantity>1</Quantity>
			<DeliveredQuantity>1</DeliveredQuantity>
		</Item>
	</LineInformation>
	<Totals />
</SALESINVOICE>

My 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>
 
  <!-- Delete PackingslipId and DeliveryDate on HeaderInformation, if PackingslipId on Line is different -->  
  <xsl:template match="HeaderInformation[PackingslipId != LineInformation/Item/PackingslipId]/*[self::PackingslipId or self::DeliveryDate]" />
    
   <xsl:template match="LineInformation_TEMP">
    <xsl:apply-templates select="node()"/>
  </xsl:template>
    
  <!-- 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()='']"/>
 delete empty nodes -->
 
</xsl:stylesheet>

Correct XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<SALESINVOICE>
	<Interchange>
		<Recipient></Recipient>
		<Sender></Sender>
		<CreationDate></CreationDate>
		<Test></Test>
		<Interchange_Control_Number></Interchange_Control_Number>
	</Interchange>
	<HeaderInformation>
		<OrigInvoiceNumber>1</OrigInvoiceNumber>
		<InvoiceType>INVOIC</InvoiceType>
		<InvoiceDate>2019.01.23</InvoiceDate>
		<InvoiceNumber></InvoiceNumber>
		<PurchOrderReference>fddf</PurchOrderReference>
		<SalesOrderReference></SalesOrderReference>
		<CustomerOrderReference>fdgfdg</CustomerOrderReference>		
		<Currency></Currency>
		<WeightAndVolume />
		<DeliveryAddressInformation>
			<Name></Name>
			<Street></Street>
			<ZipCode></ZipCode>
			<City></City>
			<Country></Country>
		</DeliveryAddressInformation>
		<InvoiceAddressInformation>
			<GLN></GLN>
			<Name></Name>
			<Street></Street>
			<ZipCode></ZipCode>
			<City></City>
			<Country></Country>
			<VATNum></VATNum>
			<InternalNumber></InternalNumber>
		</InvoiceAddressInformation>
		<BuyerAddressInformation />
		<SupplierAddressInformation>
			<GLN></GLN>
			<Name></Name>
			<Street></Street>
			<ZipCode></ZipCode>
			<City></City>
			<Country></Country>
			<VATNum></VATNum>
			<Contact />
		</SupplierAddressInformation>
	</HeaderInformation>
	<LineInformation>
		<Item>
			<OrderLineNum>1</OrderLineNum>
			<GTIN></GTIN>
			<GTINDescription></GTINDescription>
			<PackingslipId>1079304</PackingslipId>
			<DeliveryDate>2019.01.23</DeliveryDate>
			<SupplierArticleNumber></SupplierArticleNumber>
			<Quantity>1</Quantity>
			<DeliveredQuantity>1</DeliveredQuantity>
		</Item>
	</LineInformation>
	<LineInformation>
		<Item>
			<OrderLineNum>2</OrderLineNum>
			<GTIN></GTIN>
			<GTINDescription>/GTINDescription>
			<PackingslipId>1079305</PackingslipId>
			<DeliveryDate>2019.01.23</DeliveryDate>
			<SupplierArticleNumber></SupplierArticleNumber>
			<Quantity>1</Quantity>
			<DeliveredQuantity>1</DeliveredQuantity>
		</Item>
	</LineInformation>
	<Totals />
</SALESINVOICE>

Best regards Julian

Upvotes: 1

Views: 646

Answers (1)

Tim C
Tim C

Reputation: 70648

The problem is that LineInformation is not a child of HeaderInformation, but a sibling, so use the .. to get the parent element, and so then get the siblings, like so....

<xsl:template match="HeaderInformation[PackingslipId != ../LineInformation/Item/PackingslipId]
                     /*[self::PackingslipId or self::DeliveryDate]" />

EDIT: If you wanted to do it without the conditional expression in the match for whatever reason, try this XSLT instead...

<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>

  <!-- Delete PackingslipId and DeliveryDate on HeaderInformation, if PackingslipId on Line is different -->  
  <xsl:template match="HeaderInformation">
    <xsl:copy>
      <xsl:choose>
        <xsl:when test="PackingslipId != ../LineInformation/Item/PackingslipId">
          <xsl:apply-templates select="node()|@*" mode="exclude" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates select="node()|@*" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="PackingslipId|DeliveryDate" mode="exclude" />

  <xsl:template match="node()|@*" mode="exclude">
    <xsl:copy>
     <xsl:apply-templates select="node()|@*" mode="exclude" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Upvotes: 2

Related Questions