[xsl] How to get unique attribute values for nodes having few constraint

Subject: [xsl] How to get unique attribute values for nodes having few constraint
From: Dipesh Khakhkhar <dkhakhkh@xxxxxxxxxxxxxxx>
Date: Tue, 2 Sep 2003 15:54:28 -0400
Hi,

I am having the following xml.

XML
===

<?xml version="1.0" encoding="UTF-8"?>
<!-- edited with XMLSPY v5 rel. 4 U (http://www.xmlspy.com) by Dipesh 
Khakhkhar (Fidelity Investments) -->
<AEXDATAEXTRACT DTD_VERSION="2.2" EXTRACT_START_DATETIME="1/9/2003 4:49:39 PM" 
EXTRACT_TYPE="FULL" EXTRACT_COLLECTION="">
	<RESOURCE_TYPE GUID="{493435f7-3b17-4c4c-b07f-c23e7ab7781f}" NAME="Computer" 
DESCRIPTION="Asset Type definition for Computer" SOURCE="Asset" 
CREATED_DATE="7/16/2002 5:22:23 PM" MODIFIED_DATE="9/23/2002 2:17:48 PM" 
DELETED="0">
		<RESOURCE GUID="{C116FCBF-5B94-4F15-BF95-5795DBD384CD}" 
NAME="ALTIRISTEST_CPQ" SOURCE="" SITE_CODE="756win" DOMAIN="FIDD" 
SYSTEM_TYPE="Win32" OS_NAME="Microsoft Windows XP" OS_TYPE="Professional" 
OS_VERSION="5.1" OS_REVISION="Service Pack 1" LAST_LOGON_USER="" 
LAST_LOGON_DOMAIN="">
			<INVENTORY>
				<ASSET>
					<IDENTIFICATION IDentId="ytwyu">
						<ATTRIBUTE NAME="Name">ALTIRISTEST_CPQ</ATTRIBUTE>
						<ATTRIBUTE NAME="Domain">FIDDOMRTLSLC</ATTRIBUTE>
						<ATTRIBUTE NAME="Altkey1" NULL="FALSE"/>
						<ATTRIBUTE NAME="Altkey2">00-02-A5-1A-67-A6</ATTRIBUTE>
					</IDENTIFICATION>
					<CLASS NAME="Active_Directory_Details">
						<OBJECT>
							<ATTRIBUTE NAME="Agent Name">Altiris eXpress NS Client</ATTRIBUTE>
							<ATTRIBUTE NAME="Product Version">5.5.0.517</ATTRIBUTE>
							<ATTRIBUTE NAME="Build Number">517</ATTRIBUTE>
							<ATTRIBUTE NAME="Install Path">C:\Program Files\Altiris\eXpress\NS 
Client</ATTRIBUTE>
						</OBJECT>
						<OBJECT>
							<ATTRIBUTE NAME="Agent Name">Altiris eXpress NS Client</ATTRIBUTE>
							<ATTRIBUTE NAME="Product Version">5.5.0.517</ATTRIBUTE>
							<ATTRIBUTE NAME="Build Number">517</ATTRIBUTE>
							<ATTRIBUTE NAME="Install Path">C:\Program Files\Altiris\eXpress\NS 
Client</ATTRIBUTE>
						</OBJECT>
<OBJECT>
							<ATTRIBUTE NAME="Not_Counted">This is not catpured</ATTRIBUTE>
</OBJECT>
					</CLASS>
					<CLASS NAME="User_Contact_Details">
						<OBJECT>
							<ATTRIBUTE NAME="Collection Time">1/9/2003 3:06:56 AM</ATTRIBUTE>
							<ATTRIBUTE NAME="File Count">3</ATTRIBUTE>
							<ATTRIBUTE NAME="Total Size">139271</ATTRIBUTE>
							<ATTRIBUTE NAME="Version">5: 5: 0: 423</ATTRIBUTE>
						</OBJECT>
						<OBJECT>
							<ATTRIBUTE NAME="Collection Time">Second Row First Column of 
UCD</ATTRIBUTE>
							<ATTRIBUTE NAME="File Count">Second Row Second Column of 
UCD</ATTRIBUTE>
							<ATTRIBUTE NAME="Total Size">Second Row Third Column of UCD</ATTRIBUTE>
							<ATTRIBUTE NAME="Version">Second Row Third Column of UCD</ATTRIBUTE>
						</OBJECT>
					</CLASS>
					<CLASS NAME="User_General_Details">
						<OBJECT>
							<ATTRIBUTE NAME="Collection Time">1/9/2003 3:06:56 AM</ATTRIBUTE>
							<ATTRIBUTE NAME="File Count">3</ATTRIBUTE>
							<ATTRIBUTE NAME="Total Size">139271</ATTRIBUTE>
							<ATTRIBUTE NAME="Version">5: 5: 0: 423</ATTRIBUTE>
						</OBJECT>
						<OBJECT>
							<ATTRIBUTE NAME="Collection Time">Second Row First Column of 
UGD</ATTRIBUTE>
							<ATTRIBUTE NAME="File Count">Second Row Second Column of 
UGD</ATTRIBUTE>
							<ATTRIBUTE NAME="Total Size">Second Row Third Column of UGD</ATTRIBUTE>
							<ATTRIBUTE NAME="Version">Second Row Third Column of UGD</ATTRIBUTE>
						</OBJECT>
					</CLASS>

				</ASSET>
			</INVENTORY>
		</RESOURCE>
		<RESOURCE GUID="{C116FCBF-5B94-4F15-BF95-5795DBD384CD}" 
NAME="ALTIRISTEST_CPQ" SOURCE="" SITE_CODE="756win" DOMAIN="FIDD" 
SYSTEM_TYPE="Win32" OS_NAME="Microsoft Windows XP" OS_TYPE="Professional" 
OS_VERSION="5.1" AdditionalCol="Working Additional Col Value" 
OS_REVISION="Service Pack 1" LAST_LOGON_USER="" LAST_LOGON_DOMAIN="">
			<INVENTORY>
				<ASSET>
					<IDENTIFICATION>
						<ATTRIBUTE NAME="Name">ALTIRISTEST_CPQ</ATTRIBUTE>
						<ATTRIBUTE NAME="Additional Column">additional column value</ATTRIBUTE>
						<ATTRIBUTE NAME="Domain">FIDDOMRTLSLC</ATTRIBUTE>
						<ATTRIBUTE NAME="Altkey1" NULL="FALSE"/>
						<ATTRIBUTE NAME="Altkey2">00-02-A5-1A-67-A6</ATTRIBUTE>
					</IDENTIFICATION>
					<CLASS NAME="Active_Directory_Details">
						<OBJECT>
							<ATTRIBUTE NAME="Agent Name">Altiris eXpress NS Client</ATTRIBUTE>
							<ATTRIBUTE NAME="Product Version">5.5.0.517</ATTRIBUTE>
							<ATTRIBUTE NAME="Extra Column">Extra COlumn Value1</ATTRIBUTE>
							<ATTRIBUTE NAME="Build Number">517</ATTRIBUTE>
							<ATTRIBUTE NAME="Install Path">C:\Program Files\Altiris\eXpress\NS 
Client</ATTRIBUTE>
						</OBJECT>
					</CLASS>
				</ASSET>
			</INVENTORY>
		</RESOURCE>
	</RESOURCE_TYPE>
</AEXDATAEXTRACT>


---------------------------------------------------------------------

I wanted output like this.

Output
=======

SEQUENCEID`DTD_VERSION`EXTRACT_START_DATETIME`EXTRACT_TYPE`EXTRACT_COLLECTION`
SEQUENCEID`RESOURCE_TYPE.GUID`NAME`DESCRIPTION`SOURCE`CREATED_DATE`MODIFIED_DA
TE`DELETED`RESOURCE_TYPE.GUID`RESOURCE.GUID`NAME`SOURCE`SITE_CODE`DOMAIN`SYSTE
M_TYPE`OS_NAME`OS_TYPE`OS_VERSION`AdditionalCol`OS_REVISION`LAST_LOGON_USER`LA
ST_LOGON_DOMAIN`INVENTORYID`RESOURCE.GUID`INVENTORYID`ASSETID`NAME`IDENTIFICAT
IONID`ASSETID`Name`Additional 
Column`Domain`Altkey1`Altkey2`ActiveDirectoryDetailsID`AssetID`Agent 
Name`Product Version`Extra Column`Build Number`Install 
Path`UserContactDetailsID`AssetID`Collection Time`File Count`Total 
Size`Version`UserGeneralDetailsID`AssetID`Collection Time`File Count`Total 
Size`Version
AutoSequence`2.2`1/9/2003 4:49:39 
PM`FULL``SEQID`{493435f7-3b17-4c4c-b07f-c23e7ab7781f}`Computer`Asset Type 
definition for Computer`Asset`7/16/2002 5:22:23 PM`9/23/2002 2:17:48 
PM`0`{493435f7-3b17-4c4c-b07f-c23e7ab7781f}`{C116FCBF-5B94-4F15-BF95-5795DBD38
4CD}`ALTIRISTEST_CPQ``756win`FIDD`Win32`Microsoft Windows 
XP`Professional`5.1``Service Pack 
1```IDAEB2N`{C116FCBF-5B94-4F15-BF95-5795DBD384CD}`IDAEB2N`IDAGB2N`IDENTIFICAT
ION`IDAIB2N`IDAGB2N`ALTIRISTEST_CPQ``FIDDOMRTLSLC``00-02-A5-1A-67-A6
`````````````````````````````IDAGB2N`IDAEB2N`Active_Directory_Details````````I
DA4B2N`IDAGB2N`Altiris eXpress NS Client`5.5.0.517``517`C:\Program 
Files\Altiris\eXpress\NS Client
```````````````````````````````````````IDARC2N`IDAGB2N`Altiris eXpress NS 
Client`5.5.0.517``517`C:\Program Files\Altiris\eXpress\NS Client
`````````````````````````````IDAGB2N`IDAEB2N`User_Contact_Details`````````````
``IDAID2N`IDAGB2N`1/9/2003 3:06:56 AM`3`139271`5: 5: 0: 423
``````````````````````````````````````````````IDA1D2N`IDAGB2N`Second Row First 
Column of UCD`Second Row Second Column of UCD`Second Row Third Column of 
UCD`Second Row Third Column of UCD
`````````````````````````````IDAGB2N`IDAEB2N`User_General_Details`````````````
````````IDASE2N`IDAGB2N`1/9/2003 3:06:56 AM`3`139271`5: 5: 0: 423
````````````````````````````````````````````````````IDAFF2N`IDAGB2N`Second Row 
First Column of UGD`Second Row Second Column of UGD`Second Row Third Column of 
UGD`Second Row Third Column of UGD
`````````````{493435f7-3b17-4c4c-b07f-c23e7ab7781f}`{C116FCBF-5B94-4F15-BF95-5
795DBD384CD}`ALTIRISTEST_CPQ``756win`FIDD`Win32`Microsoft Windows 
XP`Professional`5.1`Working Additional Col Value`Service Pack 
1```IDALG2N`{C116FCBF-5B94-4F15-BF95-5795DBD384CD}`IDALG2N`IDANG2N`IDENTIFICAT
ION`IDAPG2N`IDANG2N`ALTIRISTEST_CPQ`additional column 
value`FIDDOMRTLSLC``00-02-A5-1A-67-A6
`````````````````````````````IDANG2N`IDALG2N`Active_Directory_Details````````I
DAJH2N`IDANG2N`Altiris eXpress NS Client`5.5.0.517`Extra COlumn 
Value1`517`C:\Program Files\Altiris\eXpress\NS Client


--------------------------------------------------------------------

I have written the following xsl

XSL
===

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 
version="1.0">
	<xsl:output method="text"/>
	<!-- Getting AeXDataExtract node with maximum attributes -->
	<xsl:variable name="mostattForAexDataExtract">
		<xsl:for-each select="//AEXDATAEXTRACT">
			<xsl:sort select="count(attribute::*)" order="descending" 
data-type="number"/>
			<xsl:if test="position()=1">
				<xsl:value-of select="generate-id()"/>
			</xsl:if>
		</xsl:for-each>
	</xsl:variable>
	<xsl:variable name="maxAttADE-node" select="//node()[generate-id() = 
$mostattForAexDataExtract]"/>
	<!-- Getting Resource_Type node with maximum attributes -->
	<xsl:variable name="mostattForResourceType">
		<xsl:for-each select="//RESOURCE_TYPE">
			<xsl:sort select="count(attribute::*)" order="descending" 
data-type="number"/>
			<xsl:if test="position()=1">
				<xsl:value-of select="generate-id()"/>
			</xsl:if>
		</xsl:for-each>
	</xsl:variable>
	<xsl:variable name="maxAttResType-node" select="//node()[generate-id() = 
$mostattForResourceType]"/>
	<!-- Getting Resource node with maximum attributes -->
	<xsl:variable name="mostattForResource">
		<xsl:for-each select="//RESOURCE">
			<xsl:sort select="count(attribute::*)" order="descending" 
data-type="number"/>
			<xsl:if test="position()=1">
				<xsl:value-of select="generate-id()"/>
			</xsl:if>
		</xsl:for-each>
	</xsl:variable>
	<xsl:variable name="maxAttResource-node" select="//node()[generate-id() = 
$mostattForResource]"/>
	<!-- Getting Identification node with maximum childnodes i.e. having maximum 
columns-->
	<xsl:variable name="mostattIdentification">
		<xsl:for-each select="//IDENTIFICATION">
			<xsl:sort select="count(ATTRIBUTE)" order="descending"/>
			<xsl:if test="position()=1">
				<xsl:value-of select="generate-id(.)"/>
			</xsl:if>
		</xsl:for-each>
	</xsl:variable>
	<xsl:variable name="maxAttIdentification-node" select="//node()[generate-id() 
= $mostattIdentification]"/>
	<!-- Getting Active_Directory_Details node with maximum childnodes i.e. 
having maximum columns-->
	<xsl:variable name="mostattActDirDetTable">
	<xsl:for-each 
select="/AEXDATAEXTRACT/RESOURCE_TYPE/RESOURCE/INVENTORY/ASSET/CLASS[normalize
-space(@NAME)='Active_Directory_Details']/OBJECT">
		<xsl:sort select="count(ATTRIBUTE)" data-type="number" order="descending"/>
			<xsl:if test="position()=1">
				<xsl:value-of select="generate-id(.)"/>
			</xsl:if>
	</xsl:for-each>
</xsl:variable>
<xsl:variable name="maxattActDirDet-node" select="//node()[generate-id() = 
$mostattActDirDetTable]"/>
<!-- Getting User_Contact_Details node with maximum childnodes i.e. having 
maximum columns-->
<xsl:variable name="mostattUserConDetTable">
	<xsl:for-each 
select="/AEXDATAEXTRACT/RESOURCE_TYPE/RESOURCE/INVENTORY/ASSET/CLASS[normalize
-space(@NAME)='User_Contact_Details']/OBJECT">
		<xsl:sort select="count(ATTRIBUTE)" data-type="number" order="descending"/>
			<xsl:if test="position()=1">
				<xsl:value-of select="generate-id(.)"/>
			</xsl:if>
	</xsl:for-each>
</xsl:variable>
<xsl:variable name="maxattUserConDet-node" select="//node()[generate-id() = 
$mostattUserConDetTable]"/>
<!-- Getting User_General_Details node with maximum childnodes i.e. having 
maximum columns-->
<xsl:variable name="mostattUserGenDetTable">
	<xsl:for-each 
select="/AEXDATAEXTRACT/RESOURCE_TYPE/RESOURCE/INVENTORY/ASSET/CLASS[normalize
-space(@NAME)='User_General_Details']/OBJECT">
		<xsl:sort select="count(ATTRIBUTE)" data-type="number" order="descending"/>
			<xsl:if test="position()=1">
				<xsl:value-of select="generate-id(.)"/>
			</xsl:if>
	</xsl:for-each>
</xsl:variable>
<xsl:variable name="maxattUserGenDet-node" select="//node()[generate-id() = 
$mostattUserGenDetTable]"/>

	<!-- Outputting Column Header first and Then Data -->
	<xsl:template match="/">
		<!-- Printing header for AeXDataExtract -->
		<xsl:text>SEQUENCEID`</xsl:text>
		<xsl:for-each select="$maxAttADE-node/@*">
			<xsl:value-of select="name(.)"/>
			<xsl:if test="position()!=last()">`</xsl:if>
		</xsl:for-each>
		<!-- Printing header for resource type -->
		<xsl:text>`SEQUENCEID`RESOURCE_TYPE.</xsl:text>
		<xsl:for-each select="$maxAttResType-node/@*">
			<xsl:value-of select="name(.)"/>
			<xsl:if test="position()!=last()">`</xsl:if>
		</xsl:for-each>
		<!-- Printing header for resource -->
		<xsl:text>`RESOURCE_TYPE.GUID`RESOURCE.</xsl:text>
		<xsl:for-each select="$maxAttResource-node/@*">
			<xsl:value-of select="name(.)"/>
			<xsl:if test="position()!=last()">`</xsl:if>
		</xsl:for-each>
		<!-- Printing header for Inventory and Asset Tables -->
		<xsl:text>`INVENTORYID`RESOURCE.GUID`INVENTORYID`ASSETID`NAME`</xsl:text>
		<!-- Printing header for IDENTIFICATION -->
		<xsl:text>IDENTIFICATIONID`ASSETID`</xsl:text>
		<xsl:for-each select="$maxAttIdentification-node">
			<xsl:for-each select="ATTRIBUTE/@NAME">
				<xsl:value-of select="."/>
				<xsl:if test="position()!=last()">`</xsl:if>
			</xsl:for-each>
		</xsl:for-each>
		<!-- Printing header for Active_Directory_Details  -->
<xsl:for-each select="$maxattActDirDet-node">
	<xsl:text>`ActiveDirectoryDetailsID`AssetID`</xsl:text>
	<xsl:for-each select="ATTRIBUTE/@NAME">
		<xsl:value-of select="."/>
		<xsl:if test="position()!=last()">`</xsl:if>
	</xsl:for-each>
</xsl:for-each>
		<!-- Printing header for User_Contact_Details -->
<xsl:for-each select="$maxattUserConDet-node">
	<xsl:text>`UserContactDetailsID`AssetID`</xsl:text>
	<xsl:for-each select="ATTRIBUTE/@NAME">
		<xsl:value-of select="."/>
		<xsl:if test="position()!=last()">`</xsl:if>
	</xsl:for-each>
</xsl:for-each>
		<!-- Printing header for User_General_Details -->
<xsl:for-each select="$maxattUserGenDet-node">
	<xsl:text>`UserGeneralDetailsID`AssetID`</xsl:text>
	<xsl:for-each select="ATTRIBUTE/@NAME">
		<xsl:value-of select="."/>
		<xsl:if test="position()!=last()">`</xsl:if>
	</xsl:for-each>
</xsl:for-each>
		<xsl:text>&#10;</xsl:text>
		<!-- Now putting data data below the Column Headers -->
		<xsl:apply-templates select="/AEXDATAEXTRACT"/>
	</xsl:template>
	<!-- Template for AEXDATAEXTRACT -->
	<xsl:template match="AEXDATAEXTRACT">
		<xsl:text>AutoSequence`</xsl:text>
		<xsl:variable name="r" select="."/>
		<xsl:for-each select="$maxAttADE-node">
			<xsl:for-each select="@*">
				<xsl:choose>
					<xsl:when test="$r/@*[name()=name(current())]">
						<xsl:value-of select="."/>
						<xsl:if test="position()!=last()">`</xsl:if>
					</xsl:when>
					<xsl:otherwise>`</xsl:otherwise>
				</xsl:choose>
			</xsl:for-each>
			<!--<xsl:text>&#10;</xsl:text> -->
		</xsl:for-each>
		<xsl:apply-templates select="RESOURCE_TYPE"/>
	</xsl:template>
	<!-- Template for resouce Type -->
	<xsl:template match="RESOURCE_TYPE">
		<xsl:text>`SEQID`</xsl:text>
		<xsl:variable name="r" select="."/>
		<xsl:for-each select="$maxAttResType-node">
			<xsl:for-each select="@*">
				<xsl:choose>
					<xsl:when test="$r/@*[name()=name(current())]">
						<xsl:value-of select="."/>
						<xsl:if test="position()!=last()">`</xsl:if>
					</xsl:when>
					<xsl:otherwise>`</xsl:otherwise>
				</xsl:choose>
			</xsl:for-each>
			<!--<xsl:text>&#10;</xsl:text> -->
		</xsl:for-each>
		<xsl:apply-templates select="RESOURCE"/>
		<!-- I will count the attributes of parent node and dynamically generate the 
seperators -->
		<xsl:if test="not (position()=last())">
			<!--	<xsl:text>
`````</xsl:text> -->
			<xsl:text>
</xsl:text>
			<xsl:call-template name="do-quotes">
				<xsl:with-param name="count" select="count($maxAttADE-node/@*) + 1"/>
			</xsl:call-template>
		</xsl:if>
	</xsl:template>
	<!-- Template for RESOURCE -->
	<xsl:template match="RESOURCE">`<xsl:value-of 
select="../@GUID"/>`<xsl:variable name="r" select="."/>
		<xsl:for-each select="$maxAttResource-node">
			<xsl:for-each select="@*">
				<xsl:choose>
					<xsl:when test="$r/@*[name()=name(current())]">
						<xsl:value-of select="."/>
						<xsl:if test="position()!=last()">`</xsl:if>
					</xsl:when>
					<xsl:otherwise>`</xsl:otherwise>
				</xsl:choose>
			</xsl:for-each>
			<!-- <xsl:text>&#10;</xsl:text> -->
		</xsl:for-each>
		<xsl:apply-templates select="INVENTORY"/>
		<xsl:if test="not (position()=last())">
			<!--<xsl:text>
````````````</xsl:text> -->
			<!-- Calling doQuotes template which writes qoutes in the output -->
			<xsl:call-template name="do-quotes">
				<xsl:with-param name="count" select="count($maxAttADE-node/@*) + 1 + 
count($maxAttResType-node/@*)"/>
			</xsl:call-template>
		</xsl:if>
	</xsl:template>
	<!-- Template for INVENTORY -->
	<xsl:template match="INVENTORY">`<xsl:value-of 
select="generate-id(.)"/>`<xsl:value-of select="..//@GUID"/>
		<xsl:apply-templates select="ASSET"/>
	</xsl:template>
	<!-- Template for ASSET -->
	<xsl:template match="ASSET">`<xsl:value-of 
select="generate-id(..)"/>`<xsl:value-of select="generate-id(.)"/>
		<xsl:apply-templates select="IDENTIFICATION"/>
		<xsl:apply-templates select="CLASS"/>
	</xsl:template>
	<!--Temaplate for IDENTIFICATION -->
	<xsl:template match="IDENTIFICATION">`IDENTIFICATION`<xsl:value-of 
select="generate-id(.)"/>`<xsl:value-of select="generate-id(..)"/>
		<xsl:text>`</xsl:text>
		<xsl:variable name="r" select="."/>
		<xsl:for-each select="$maxAttIdentification-node/ATTRIBUTE">
			<xsl:value-of 
select="normalize-space($r/ATTRIBUTE[@NAME=current()/@NAME])"/>
			<xsl:if test="position()!=last()">`</xsl:if>
		</xsl:for-each>
		<xsl:text>&#10;</xsl:text>
	</xsl:template>

	<xsl:template match="CLASS">
	<xsl:choose>
		<!-- When Name is Active Directory Details -->
		<xsl:when 
test="normalize-space(@NAME)='Active_Directory_Details'">`<xsl:call-template 
name="do-quotes"><xsl:with-param name="count" 
select="count($maxAttADE-node/@*) + 1 + count($maxAttResType-node/@*) + 
count($maxAttResource-node/@*)+ 3"/></xsl:call-template><xsl:value-of 
select="generate-id(..)"/>`<xsl:value-of 
select="generate-id(../..)"/>`<xsl:value-of select="@NAME"/><xsl:call-template 
name="do-quotes"><xsl:with-param name="count" 
select="count($maxAttIdentification-node/ATTRIBUTE/@*)+ 
1"/></xsl:call-template><xsl:for-each select="OBJECT"><xsl:variable name="r" 
select="."/>`<xsl:value-of select="generate-id(.)"/>`<xsl:value-of 
select="generate-id(../..)"/><xsl:text>`</xsl:text>
			<xsl:for-each select="$maxattActDirDet-node/ATTRIBUTE">
			<xsl:value-of 
select="normalize-space($r/ATTRIBUTE[@NAME=current()/@NAME])"/>
			<xsl:if test="position()!=last()">`</xsl:if>
		</xsl:for-each>
<xsl:if test="not (position()=last())">
<xsl:text>
</xsl:text>
<xsl:call-template name="do-quotes">
<xsl:with-param name="count" select="count($maxAttADE-node/@*) + 1 + 
count($maxAttResType-node/@*) + count($maxAttResource-node/@*)+ 
count($maxAttIdentification-node/@*)+ 13"/>
</xsl:call-template>
</xsl:if>
</xsl:for-each>
<xsl:text>&#10;</xsl:text> 
</xsl:when>
		<!-- When name is User Contact Details -->
		<xsl:when 
test="normalize-space(@NAME)='User_Contact_Details'">`<xsl:call-template 
name="do-quotes"><xsl:with-param name="count" 
select="count($maxAttADE-node/@*) + 1 + count($maxAttResType-node/@*) + 
count($maxAttResource-node/@*)+ 3"/></xsl:call-template><xsl:value-of 
select="generate-id(..)"/>`<xsl:value-of 
select="generate-id(../..)"/>`<xsl:value-of select="@NAME"/><xsl:call-template 
name="do-quotes"><xsl:with-param name="count" 
select="count($maxAttIdentification-node/ATTRIBUTE/@*)+count($maxattActDirDet-
node/ATTRIBUTE/@*)+ 3"/></xsl:call-template><xsl:for-each 
select="OBJECT"><xsl:variable name="r" select="."/>`<xsl:value-of 
select="generate-id(.)"/>`<xsl:value-of 
select="generate-id(../..)"/><xsl:text>`</xsl:text>
			<xsl:for-each select="$maxattUserConDet-node/ATTRIBUTE">
			<xsl:value-of 
select="normalize-space($r/ATTRIBUTE[@NAME=current()/@NAME])"/>
			<xsl:if test="position()!=last()">`</xsl:if>
		</xsl:for-each>
<xsl:if test="not (position()=last())">
<xsl:text>
</xsl:text>
<xsl:call-template name="do-quotes">
<xsl:with-param name="count" select="count($maxAttADE-node/@*) + 1 + 
count($maxAttResType-node/@*) + count($maxAttResource-node/@*)+ 
count($maxAttIdentification-node/@*)+count($maxattUserConDet-node/ATTRIBUTE/@*
)+ 16"/>
</xsl:call-template>
</xsl:if>
</xsl:for-each>
<xsl:text>&#10;</xsl:text> 
</xsl:when>
		<!-- When name is User General Details -->
		<xsl:when 
test="normalize-space(@NAME)='User_General_Details'">`<xsl:call-template 
name="do-quotes"><xsl:with-param name="count" 
select="count($maxAttADE-node/@*) + 1 + count($maxAttResType-node/@*) + 
count($maxAttResource-node/@*)+ 3"/></xsl:call-template><xsl:value-of 
select="generate-id(..)"/>`<xsl:value-of 
select="generate-id(../..)"/>`<xsl:value-of select="@NAME"/><xsl:call-template 
name="do-quotes"><xsl:with-param name="count" 
select="count($maxAttIdentification-node/ATTRIBUTE/@*)+count($maxattActDirDet-
node/ATTRIBUTE/@*)+count($maxattUserConDet-node/ATTRIBUTE/@*)+ 
5"/></xsl:call-template><xsl:for-each select="OBJECT"><xsl:variable name="r" 
select="."/>`<xsl:value-of select="generate-id(.)"/>`<xsl:value-of 
select="generate-id(../..)"/><xsl:text>`</xsl:text>
			<xsl:for-each select="$maxattUserGenDet-node/ATTRIBUTE">
			<xsl:value-of 
select="normalize-space($r/ATTRIBUTE[@NAME=current()/@NAME])"/>
			<xsl:if test="position()!=last()">`</xsl:if>
		</xsl:for-each>
<xsl:if test="not (position()=last())">
<xsl:text>
</xsl:text>
<xsl:call-template name="do-quotes">
<xsl:with-param name="count" select="count($maxAttADE-node/@*) + 1 + 
count($maxAttResType-node/@*) + count($maxAttResource-node/@*)+ 
count($maxAttIdentification-node/@*)+count($maxattActDirDet-node/ATTRIBUTE/@*)
+count($maxattUserConDet-node/ATTRIBUTE/@*)+ 17"/>
</xsl:call-template>
</xsl:if>
</xsl:for-each>
<xsl:text>&#10;</xsl:text> 
</xsl:when>
	</xsl:choose>
	</xsl:template>

	<!-- RECURSIVE TEMPLATE TO OUTPUT DELIMTER i.e " `" -->
	<xsl:template name="do-quotes">
		<xsl:param name="count" select="0"/>
		<xsl:if test="$count">
			<xsl:text>`</xsl:text>
			<xsl:call-template name="do-quotes">
				<xsl:with-param name="count" select="$count - 1"/>
			</xsl:call-template>
		</xsl:if>
	</xsl:template>
</xsl:stylesheet>


--------------------------------------------------------------------

This is working fine.  I am trying to get the column headers first and then 
data for respective columns. Column headers are the attributes. These i am 
capturing sometimes directly and sometimes in a round about way (for CLASS 
nodes).

To get the column headers i am finding node having maximum attribute and node 
having maximum child nodes of type ATTRIBUTE.

To get the column data, I am comparing the node attribute by attribute and 
wherever they are same, I am outputting the value and where they are not 
putting delimiter.

Now I am having two issues.

1) As you can see in the input xml, if within 
CLASS/@Name="'Active_Directory_Details'"/OBJECT node i have a node (ATTRIBUTE 
)having only one attribute with name Not_Counted. I found the node 
(CLASS/OBJECT) in which CLASS has attribute with name 
"'Active_Directory_Details'" having maximum ATTRIBUTE nodes. From this i got 
the column header. But i missed the column with name="Not_Counted".

Keeping everything as shown in the above xsl as it is, how do i get this into 
column header. And how do i use it to get the data ?


2) My dtd says that i can have any number of CLASS nodes. Here after doing all 
these i feel that I have hardcoded, infact i had. 
To make it generic can i dynamically do this ? Will that be very tough ?

Eagerly waiting for reply. Thanks in the anticipation that I will get some 
hints and suggestions.

Regards,
Dipesh


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread