We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you a podcast all about Citrix Workspace, moving to the cloud, and analytics & intelligence. Episode 2 coming soon!Listen Now

x

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

bjh1977
bjh1977 asked
on
Medium Priority
629 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

Comment
Watch Question

Author

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

Information Architect
CERTIFIED EXPERT
Top Expert 2006
Commented:
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
                 

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts
Gertone (Geert Bormans)Information Architect
CERTIFIED EXPERT
Top Expert 2006

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

Author

Commented:
He's done it again!

Author

Commented:
sorry - (s)he's done it again!
Gertone (Geert Bormans)Information Architect
CERTIFIED EXPERT
Top Expert 2006

Commented:
you can safely say "he" :-)
welcome
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.