[xsl] Unique, Maximum Attributes with a node ??

Subject: [xsl] Unique, Maximum Attributes with a node ??
From: Dipesh Khakhkhar <dkhakhkh@xxxxxxxxxxxxxxx>
Date: Wed, 3 Sep 2003 11:43:47 -0400
Hi,

First of all sorry for writing a long email. But to explain the problem 
clearly I am pasting my xml, xsl and output. (This will look weird initially 
but when copy pasted in some file, it will give good look).

The situation is like I have to find the node which contains maximum child 
nodes and this child node in turn contains attributes. I got this node. Now I 
am missing some node having child nodes which have attributes which are not 
present in the node having maximum child nodes. Since these attributes maps to 
my database columns, I need to get all the possible attributes for a given 
node. Then i am getting the data for all such node by comparing attribute 
names. In my solution below I have shown how i have used to get data. When the 
output is pasted on the excel sheet. Then go to Data => Text to column => 
mentioning other "`" this back quote as a delimter , it will give column 
header and respective column data. This is what i am ulitimately trying to 
achieve.

Problem
----------
How do i prevent missing such column name ?


Possible solutions
------------------
1)
I have written the xsl from which i get the node having having maximum child 
nodes. In other words i am getting a node with maximum attributes. But here i 
may miss few attributes which are in other node. Now if i have to get that 
missing attribute is this the solution.

I have stored the node in the variable. Do i have to copy the new attribute in 
the existing one and create new node ? But will i be able to use this node 
directly to get the data ?

2)
Do I have to create new node in the new xml file and later used them as the 
variable in the xsl to get column header and column data ?

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>


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

The above xsl is working fine.
The other issue which i am having is how to make my xsl dynamic.

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

(PS: Sorry once again for writing such a huge email )


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


Current Thread