XSLT Newbie - XSL:If Question

Here should go questions about transforming XML with XSLT and FOP.
tracy.giles
Posts: 2
Joined: Tue Aug 07, 2007 12:22 pm
Location: Cirencester

XSLT Newbie - XSL:If Question

Post by tracy.giles »

Hello

I'm new to XSLT and am reading XML file and need to output to a CSV file. I am having problems doing the following:

1. When the attribute VoidFlag = True, do not write to output file.
2. If node = 'Return', then set literal flag (RefundInd) = Y

My xml file is

- <POSLog xmlns="http://www.nrf-arts.org/IXRetail/namespace/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.nrf-arts.org/IXRetail/namespace/ POSLog.xsd">
- <Transaction CancelFlag="false" TrainingModeFlag="false" OfflineFlag="false" VersionNumber="5.0.0.0">
<RetailStoreID>1</RetailStoreID>
<WorkstationID>1</WorkstationID>
<SequenceNumber>4</SequenceNumber>
<BeginDateTime>2007-07-18T13:08:00</BeginDateTime>
<OperatorID>1</OperatorID>
<CurrencyCode>EUR</CurrencyCode>
<TlogName>3.tlg</TlogName>
<TlogOffset>898</TlogOffset>
- <RetailTransaction Version="2.0">
<TillID>1</TillID>
<RevenueCenterID>Location One</RevenueCenterID>
<ReceiptDateTime>2007-07-18T13:08:00</ReceiptDateTime>
- <LineItem Version="2.0" VoidFlag="false" EntryMethod="Keyed">
<SequenceNumber>1</SequenceNumber>
- <Sale ItemType="Stock">
- <POSIdentity>
<POSItemID>1</POSItemID>
</POSIdentity>
<MerchandiseHierarchy Level="Department">999</MerchandiseHierarchy>
<Description>Item Number 1</Description>
<TaxIncludedInPriceFlag>false</TaxIncludedInPriceFlag>
<ActualSalesUnitPrice>1.00</ActualSalesUnitPrice>
<ExtendedAmount>1.00</ExtendedAmount>
<Quantity>1.000</Quantity>
</Sale>
</LineItem>
- <LineItem Version="2.0" VoidFlag="false" EntryMethod="Keyed">
<SequenceNumber>2</SequenceNumber>
- <Sale ItemType="Stock">
- <POSIdentity>
<POSItemID>2</POSItemID>
</POSIdentity>
<MerchandiseHierarchy Level="Department">999</MerchandiseHierarchy>
<Description>Item Number 2</Description>
<TaxIncludedInPriceFlag>false</TaxIncludedInPriceFlag>
<ActualSalesUnitPrice>2.00</ActualSalesUnitPrice>
<ExtendedAmount>2.00</ExtendedAmount>
<Quantity>1.000</Quantity>
</Sale>
</LineItem>
- <LineItem Version="2.0" VoidFlag="false" EntryMethod="Keyed">
<SequenceNumber>3</SequenceNumber>
- <Tender TenderType="Cash" FREEDOM_TenderType="Contant" TypeCode="Sale" ChangeFlag="false">
<Amount>3.00</Amount>
</Tender>
</LineItem>
- <LineItem Version="2.0" VoidFlag="false" EntryMethod="Keyed">
<SequenceNumber>4</SequenceNumber>
- <Tax TaxType="VAT" TaxSubType="FREEDOM:0">
<SequenceNumber>1</SequenceNumber>
<TaxableAmount TaxIncludedInTaxableAmountFlag="true">3.00</TaxableAmount>
<TaxablePercentage>0.00</TaxablePercentage>
<Amount>0.00</Amount>
</Tax>
</LineItem>
</RetailTransaction>
</Transaction>
</POSLog>

and my XSLT is

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0" xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:output method="text" encoding="utf-8" />

<xsl:template match="/">
<xsl:for-each select="*/*[name()='Transaction']/*[not(*)]">
<xsl:value-of select="concat(name(.), ',')" />
</xsl:for-each>

<!-- The rest of the column headings are hard-coded here: -->
<xsl:value-of select="'TillID,RevenueCentreID,ReceiptDateTime,VoidFlag,POSItemID,MerchandiseHierarchy,Description,ActualSalesUnitPrice,Quantity,TenderType,TenderAmount,DiscountBenefit,DiscountAmount,DiscountPercentage,RefundInd'"/>

<!-- New line after the colum headings: -->
<xsl:text>
</xsl:text>

<xsl:apply-templates select="//*[name()='LineItem']/*[ contain ('Sale,Return,Discount,Tender',name()) ]" />


</xsl:template>


<!-- Output a csv row for each Sale/Return/Discount/Tender/Tax node: -->
<xsl:template match="*">

<!-- Output the value of each element in the parent "Transaction" node: -->
<!-- We want RetailStoreID and WorkstationID etc so in other words, only those without child nodes. -->
<!-- Naturally, these nodes will be the same for every LineItem inside a Transaction. -->

<xsl:for-each select="ancestor::*[name()='Transaction']/*[not(*)]">
<xsl:value-of select="concat(., ',')" />
</xsl:for-each>

<xsl:for-each select="ancestor::*[name()='RetailTransaction']/*[not(*)]">
<xsl:value-of select="concat(., ',')" />
</xsl:for-each>

<xsl:value-of select="concat( ../@VoidFlag , ',')" />
<xsl:value-of select="concat( ./*/*[name()='POSItemID'] , ',')" />

<!-- Output the value of each child element: -->
<!-- We want MerchandiseHierarchy and Description etc so in other words, only those without child nodes. -->
<!--<xsl:for-each select="*[not(*)]">
<xsl:value-of select="concat(',', .)" />
</xsl:for-each>-->

<!-- Output the value of each element in current node, with commas between them: -->
<xsl:value-of select="concat( *[name()='MerchandiseHierarchy'], ',', *[name()='Description'], ',', *[name()='ActualSalesUnitPrice'], ',', *[name()='Quantity'], ',', @TenderType, ',', *[name()='Amount'], ',', *[name()='DiscountBenefit'], ',', *[name()='Discount/Amount'], ',', *[name()='Percentage'])" />

<xsl:text>
</xsl:text>

</xsl:template>

</xsl:stylesheet>
[/list][/code]

Any help would be greatly appreciated

Many Thanks
Tracy
jkmyoung
Posts: 89
Joined: Mon Mar 06, 2006 10:13 pm

Post by jkmyoung »

<xsl:apply-templates select="//*[name()='LineItem']/*[ contain ('Sale,Return,Discount,Tender',name()) ]" />
becomes
<xsl:apply-templates selct="//LineItem/*[ contain ('Sale,Return,Discount,Tender',name()) ]"/>

To take into account VoidFlag="true"
<xsl:apply-templates selct="//LineItem[@VoidFlag = 'false']/*[ contain ('Sale,Return,Discount,Tender',name()) ]"/>
or
<xsl:apply-templates selct="//LineItem[@VoidFlag != 'true']/*[ contain ('Sale,Return,Discount,Tender',name()) ]"/>

Try to avoid use of * when possible. I also suggest using template applied to particular nodes, eg
<xsl:template match="LineItem">
tracy.giles
Posts: 2
Joined: Tue Aug 07, 2007 12:22 pm
Location: Cirencester

Post by tracy.giles »

Hi, I tried this code but it only outputs my column headings.
Post Reply