[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

XSL File - Displaying Column Header and Data Only If Node Exists

Posted on 2009-02-16
6
Medium Priority
?
577 Views
Last Modified: 2013-11-19
Hi,

I've got a two XML files.  One contains a node called <OrganisationHeader>, the other one doesn't.  With the Help of Gertone (thanks!) I've now got a stylesheet that will display the XML data in tabular format regardless of the existence or otherwise of the <OrganisationHeader> node.

Now I'm trying to only display those nodes that exist, and with my very limited knowledge of XSL I've manged to make this worj for the actual data.  Now I'm trying to do the sdame with the table headers.

Below I've included the two XML files (one with, one without the <OrganisationHeader> node) and the XSL file in its current state.  Any advice on how to conditionally show the column headings, based on whether or not the node it referes to exists?

Thanks.
XSL File So Far:
 
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:template match="/">
		<html>
			<body>
				<h2>Test Result</h2>
				<table border="1" cellpadding="3">
					<tbody>
						<tr>
							<td>RevenueCentre</td>
							<td>SalesDate</td>
							<td>Location</td>
							<td>PLU</td>
							<td>CategoryCode</td>
							<td>Quantity</td>
							<td>Description</td>
							<td>SaleType</td>
							<td>GrossSalesPrice</td>
							<td>NetSalesPrice</td>
							<td>TotalGrossSales</td>
							<td>TotalNetSales</td>
							<td>TotalVAT</td>
						</tr>
						<xsl:apply-templates select=".//SalesTransaction" />
					</tbody>
				</table>
			</body>
		</html>
	</xsl:template>
	<xsl:template match="SalesTransaction">
		<tr>
			<xsl:apply-templates select="ancestor::SalesHeader" />
			<td>
				<xsl:value-of select="PLU" />
			</td>
			<xsl:if test="count(CategoryCode) &gt; 0">
				<td>
					<xsl:value-of select="CategoryCode" />
				</td>
			</xsl:if>
			<td>
				<xsl:value-of select="Quantity" />
			</td>
			<td>
				<xsl:value-of select="Description" />
			</td>
			<xsl:if test="count(SaleType) &gt; 0">
				<td>
					<xsl:value-of select="SaleType" />
				</td>
			</xsl:if>
			<xsl:if test="count(GrossSalesPrice) &gt; 0">
				<td>
					<xsl:value-of select="GrossSalesPrice" />
				</td>
			</xsl:if>
			<xsl:if test="count(NetSalesPrice) &gt; 0">
				<td>
					<xsl:value-of select="NetSalesPrice" />
				</td>
			</xsl:if>
			<xsl:if test="count(TotalGrossSales) &gt; 0">
				<td>
					<xsl:value-of select="TotalGrossSales" />
				</td>
			</xsl:if>
			<xsl:if test="count(TotalNetSales) &gt; 0">
				<td>
					<xsl:value-of select="TotalNetSales" />
				</td>
			</xsl:if>
			<xsl:if test="count(TotalVat) &gt; 0">
				<td>
					<xsl:value-of select="TotalVAT" />
				</td>
			</xsl:if>
		</tr>
	</xsl:template>
	<xsl:template match="SalesHeader">
		<xsl:if test="count(RevenueCentre) &gt; 0">
			<td>
				<xsl:value-of select="RevenueCentre" />
			</td>
		</xsl:if>
		<td>
			<xsl:value-of select="Location" />
		</td>
		<td>
			<xsl:value-of select="SalesDate" />
		</td>
	</xsl:template>
</xsl:stylesheet>
 
 
XML File 1 (includes <OrganisationHeader> node):
 
<Header>
	<OrganisationHeader>
		<OrganisationID>12345</OrganisationID>
		<SalesHeader>
			<SalesDate>13/02/2009 16:44:17</SalesDate>
			<Location>47</Location>
			<SalesTransaction>
				<PLU>1234</PLU>
				<CategoryCode>4671</CategoryCode>
				<Description>Sample Description dfds </Description>
				<GrossSales>2.1500</GrossSales>
				<TotalGrossSales>21.25</TotalGrossSales>
				<Quantity>1</Quantity>
				<SaleType>9</SaleType>
				<RevenueCentre>123</RevenueCentre>
			</SalesTransaction>
			<SalesTransaction>
				<PLU>2345</PLU>
				<CategoryCode>4671</CategoryCode>
				<Description>Sample Description 1</Description>
				<GrossSales>4.1500</GrossSales>
				<TotalGrossSales>21.25</TotalGrossSales>
				<Quantity>1</Quantity>
				<SaleType>10</SaleType>
				<RevenueCentre>123</RevenueCentre>
			</SalesTransaction>
			<SalesTransaction>
				<PLU>64356</PLU>
				<CategoryCode>4671</CategoryCode>
				<Description>Sample Something 1</Description>
				<GrossSales>4.1500</GrossSales>
				<TotalGrossSales>21.25</TotalGrossSales>
				<Quantity>1</Quantity>
				<SaleType>10</SaleType>
				<RevenueCentre>123</RevenueCentre>
			</SalesTransaction>
			<SalesTransaction>
				<PLU>67657</PLU>
				<CategoryCode>4671</CategoryCode>
				<Description>Sample Desc 1</Description>
				<GrossSales>4.1500</GrossSales>
				<TotalGrossSales>21.25</TotalGrossSales>
				<Quantity>1</Quantity>
				<SaleType>10</SaleType>
				<RevenueCentre>123</RevenueCentre>
			</SalesTransaction>
		</SalesHeader>
	</OrganisationHeader>
</Header>
 
 
XML File 2 (does not include <OrganisationHeader> node):
 
<Header>
	<OrganisationID>12345</OrganisationID>
	<SalesHeader>
		<SalesDate>13/02/2009 16:44:17</SalesDate>
		<Location>47</Location>
		<SalesTransaction>
			<PLU>1234</PLU>
			<Description>Sample Description dfds </Description>
			<GrossSales>2.1500</GrossSales>
			<TotalNetSales>21.25</TotalNetSales>
			<Quantity>1</Quantity>
			<SaleType>9</SaleType>
			<RevenueCentre>123</RevenueCentre>
			<TotalVAT>1.25</TotalVAT>
		</SalesTransaction>
		<SalesTransaction>
			<PLU>2345</PLU>
			<Description>Sample Description 1</Description>
			<GrossSales>4.1500</GrossSales>
			<TotalNetSales>21.25</TotalNetSales>
			<Quantity>1</Quantity>
			<SaleType>10</SaleType>
			<RevenueCentre>123</RevenueCentre>
			<TotalVAT>1.25</TotalVAT>
		</SalesTransaction>
		<SalesTransaction>
			<PLU>64356</PLU>
			<Description>Sample Something 1</Description>
			<GrossSales>4.1500</GrossSales>
			<TotalNetSales>21.25</TotalNetSales>
			<Quantity>1</Quantity>
			<SaleType>10</SaleType>
			<RevenueCentre>123</RevenueCentre>
			<TotalVAT>1.25</TotalVAT>
		</SalesTransaction>
		<SalesTransaction>
			<PLU>67657</PLU>
			<Description>Sample Desc 1</Description>
			<GrossSales>4.1500</GrossSales>
			<TotalNetSales>21.25</TotalNetSales>
			<Quantity>1</Quantity>
			<SaleType>10</SaleType>
			<RevenueCentre>123</RevenueCentre>
			<TotalVAT>1.25</TotalVAT>
		</SalesTransaction>
	</SalesHeader>
</Header>

Open in new window

0
Comment
Question by:bjh1977
  • 3
  • 3
6 Comments
 

Author Comment

by:bjh1977
ID: 23649400
Okay. Got it to work.  Not very pretty though so if you think this can be done any better please show me!
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:template match="/">
		<html>
			<body>
				<h2>Test Result</h2>
				<table border="1" cellpadding="3">
					<tbody>
						<tr>
							<xsl:if test="count(Header/OrganisationHeader/SalesHeader/RevenueCentre) &gt; 0 or count(Header/SalesHeader/RevenueCentre) &gt; 0">
								<td>RevenueCentre</td>
							</xsl:if>
							
							<td>SalesDate</td>
							<td>Location</td>
							<td>PLU</td>
							<xsl:if test="count(Header/OrganisationHeader/SalesHeader/SalesTransaction/CategoryCode) &gt; 0 or count(Header/SalesHeader/SalesTransaction/CategoryCode) &gt; 0">
								<td>CategoryCode</td>
							</xsl:if>
							<td>Quantity</td>
							<td>Description</td>
							<xsl:if test="count(Header/OrganisationHeader/SalesHeader/SalesTransaction/SaleType) &gt; 0 or count(Header/SalesHeader/SalesTransaction/SaleType) &gt; 0">
								<td>SaleType</td>
							</xsl:if>
							<xsl:if test="count(Header/OrganisationHeader/SalesHeader/SalesTransaction/GrossSalesPrice) &gt; 0 or count(Header/SalesHeader/SalesTransaction/GrossSalesPrice) &gt; 0">
								<td>GrossSalesPrice</td>
							</xsl:if>
							<xsl:if test="count(Header/OrganisationHeader/SalesHeader/SalesTransaction/NetSalesPrice) &gt; 0 or count(Header/SalesHeader/SalesTransaction/NetSalesPrice) &gt; 0">
								<td>NetSalesPrice</td>
							</xsl:if>
							<xsl:if test="count(Header/OrganisationHeader/SalesHeader/SalesTransaction/TotalGrossSales) &gt; 0 or count(Header/SalesHeader/SalesTransaction/TotalGrossSales) &gt; 0">
								<td>TotalGrossSales</td>
							</xsl:if>
							<xsl:if test="count(Header/OrganisationHeader/SalesHeader/SalesTransaction/TotalNetSales) &gt; 0 or count(Header/SalesHeader/SalesTransaction/TotalNetSales) &gt; 0">
								<td>TotalNetSales</td>
							</xsl:if>
							<xsl:if test="count(Header/OrganisationHeader/SalesHeader/SalesTransaction/TotalVAT) &gt; 0 or count(Header/SalesHeader/SalesTransaction/TotalVAT) &gt; 0">
								<td>TotalVAT</td>
							</xsl:if>
 
						</tr>
						<xsl:apply-templates select=".//SalesTransaction" />
					</tbody>
				</table>
			</body>
		</html>
	</xsl:template>
	<xsl:template match="SalesTransaction">
		<tr>
			<xsl:apply-templates select="ancestor::SalesHeader" />
			<td>
				<xsl:value-of select="PLU" />
			</td>
			<xsl:if test="count(CategoryCode) &gt; 0">
				<td>
					<xsl:value-of select="CategoryCode" />
				</td>
			</xsl:if>
			<td>
				<xsl:value-of select="Quantity" />
			</td>
			<td>
				<xsl:value-of select="Description" />
			</td>
			<xsl:if test="count(SaleType) &gt; 0">
				<td>
					<xsl:value-of select="SaleType" />
				</td>
			</xsl:if>
			<xsl:if test="count(GrossSalesPrice) &gt; 0">
				<td>
					<xsl:value-of select="GrossSalesPrice" />
				</td>
			</xsl:if>
			<xsl:if test="count(NetSalesPrice) &gt; 0">
				<td>
					<xsl:value-of select="NetSalesPrice" />
				</td>
			</xsl:if>
			<xsl:if test="count(TotalGrossSales) &gt; 0">
				<td>
					<xsl:value-of select="TotalGrossSales" />
				</td>
			</xsl:if>
			<xsl:if test="count(TotalNetSales) &gt; 0">
				<td>
					<xsl:value-of select="TotalNetSales" />
				</td>
			</xsl:if>
			<xsl:if test="count(TotalVAT) &gt; 0">
				<td>
					<xsl:value-of select="TotalVAT" />
				</td>
			</xsl:if>
		</tr>
	</xsl:template>
	<xsl:template match="SalesHeader">
		<xsl:if test="count(RevenueCentre) &gt; 0">
			<td>
				<xsl:value-of select="RevenueCentre" />
			</td>
		</xsl:if>
		<td>
			<xsl:value-of select="SalesDate" />
		</td>
		<td>
			<xsl:value-of select="Location" />
		</td>
		
	</xsl:template>
</xsl:stylesheet>

Open in new window

0
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 1000 total points
ID: 23650126
Well, you can overcome the OrganisationHeader element by using a descendant rather than a child axis
           <xsl:if test="Header//SalesHeader/RevenueCentre">
                                <td>RevenueCentre</td>
                            </xsl:if>
and you don't need to count the nodes, the XPath will return false if they are not there
                 
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 23650183
And I would use a key, this is a lot more performant in order to find the nodes
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="trans" match="SalesTransaction/*" use="name()"/>
    <xsl:template match="/">
        <html>
            <body>
                <h2>Test Result</h2>
                <table border="1" cellpadding="3">
                    <tbody>
                        <tr>
                            <xsl:if test="Header//SalesHeader/RevenueCentre">
                                <td>RevenueCentre</td>
                            </xsl:if>
                            
                            <td>SalesDate</td>
                            <td>Location</td>
                            <td>PLU</td>
                            <xsl:if test="key('trans' , 'CategoryCode')">
                                <td>CategoryCode</td>
                            </xsl:if>
                            <td>Quantity</td>
                            <td>Description</td>
                            <xsl:if test="key('trans' , 'SaleType')">
                                <td>SaleType</td>
                            </xsl:if>
                            <xsl:if test="key('trans' , 'GrossSalesPrice')">
                                <td>GrossSalesPrice</td>
                            </xsl:if>
                            <xsl:if test="key('trans' , 'NetSalesPrice')">
                                <td>NetSalesPrice</td>
                            </xsl:if>
                            <xsl:if test="key('trans' , 'TotalGrossSales')">
                                <td>TotalGrossSales</td>
                            </xsl:if>
                            <xsl:if test="key('trans' , 'TotalNetSales')">
                                <td>TotalNetSales</td>
                            </xsl:if>
                            <xsl:if test="key('trans' , 'TotalVAT')">
                                <td>TotalVAT</td>
                            </xsl:if>
                            
                        </tr>
                        <xsl:apply-templates select=".//SalesTransaction" />
                    </tbody>
                </table>
            </body>
        </html>
    </xsl:template>
    <xsl:template match="SalesTransaction">
        <tr>
            <xsl:apply-templates select="ancestor::SalesHeader" />
            <td>
                <xsl:value-of select="PLU" />
            </td>
            <xsl:if test="count(CategoryCode) &gt; 0">
                <td>
                    <xsl:value-of select="CategoryCode" />
                </td>
            </xsl:if>
            <td>
                <xsl:value-of select="Quantity" />
            </td>
            <td>
                <xsl:value-of select="Description" />
            </td>
            <xsl:if test="count(SaleType) &gt; 0">
                <td>
                    <xsl:value-of select="SaleType" />
                </td>
            </xsl:if>
            <xsl:if test="count(GrossSalesPrice) &gt; 0">
                <td>
                    <xsl:value-of select="GrossSalesPrice" />
                </td>
            </xsl:if>
            <xsl:if test="count(NetSalesPrice) &gt; 0">
                <td>
                    <xsl:value-of select="NetSalesPrice" />
                </td>
            </xsl:if>
            <xsl:if test="count(TotalGrossSales) &gt; 0">
                <td>
                    <xsl:value-of select="TotalGrossSales" />
                </td>
            </xsl:if>
            <xsl:if test="count(TotalNetSales) &gt; 0">
                <td>
                    <xsl:value-of select="TotalNetSales" />
                </td>
            </xsl:if>
            <xsl:if test="count(TotalVAT) &gt; 0">
                <td>
                    <xsl:value-of select="TotalVAT" />
                </td>
            </xsl:if>
        </tr>
    </xsl:template>
    <xsl:template match="SalesHeader">
        <xsl:if test="count(RevenueCentre) &gt; 0">
            <td>
                <xsl:value-of select="RevenueCentre" />
            </td>
        </xsl:if>
        <td>
            <xsl:value-of select="SalesDate" />
        </td>
        <td>
            <xsl:value-of select="Location" />
        </td>
        
    </xsl:template>
</xsl:stylesheet>

Open in new window

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Closing Comment

by:bjh1977
ID: 31547274
He's done it again!
0
 

Author Comment

by:bjh1977
ID: 23650267
sorry - (s)he's done it again!
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 23650537
you can safely say "he" :-)
welcome
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

There are two main kinds of selectors in CSS: One is base selector like h1, h2, body, table or any existing HTML tags.  For instance, the following rule sets all paragraphs (<p> elements) to red: (CODE) CSS also allows us to define our own custom …
It's sometimes a bit tricky to use date functions in Oracle BPEL. I'll explain quickly how you can add N days to the current date. In a BPEL process this can be useful, and you can adapt it to fit your needs. First of all, let's see how to add 1 …
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:
The viewer will learn the benefit of using external CSS files and the relationship between class and ID selectors. Create your external css file by saving it as style.css then set up your style tags: (CODE) Reference the nav tag and set your prop…
Suggested Courses

834 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question