[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

[xsl] How to get node with maximum child nodes??


Subject: [xsl] How to get node with maximum child nodes??
From: Dipesh Khakhkhar <dkhakhkh@xxxxxxxxxxxxxxx>
Date: Mon, 25 Aug 2003 14:13:16 -0400

Hi,

I am having the following xml Document

Xml
====
<?xml version="1.0" encoding="UTF-8"?>
<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>
<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="Client_Agent">
<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 Inventory Solution</ATTRIBUTE>
<ATTRIBUTE NAME="Product Version">5.5.0.424</ATTRIBUTE>
<ATTRIBUTE NAME="Build Number">424</ATTRIBUTE>
<ATTRIBUTE NAME="Install Path">C:\Program Files\Altiris\eXpress\NS 
Client\Software Delivery\Software 
Packages\{01B54EB5-3679-4C73-9E10-E169D5A5EC59}</ATTRIBUTE>
</OBJECT>
</CLASS>
<CLASS NAME="Inventory_Results">
<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>
</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" 
OS_REVISION="Service Pack 1" LAST_LOGON_USER="" LAST_LOGON_DOMAIN="" 
AdditionalCol="Additional Col Value">
<INVENTORY>
<ASSET>
<CLASS NAME="Client_Agent">
<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>
<OBJECT>
<ATTRIBUTE NAME="Agent Name">Altiris eXpress Inventory Solution</ATTRIBUTE>
<ATTRIBUTE NAME="Product Version">5.5.0.424</ATTRIBUTE>
<ATTRIBUTE NAME="Extra Column">Extra COlumn Value2</ATTRIBUTE>
<ATTRIBUTE NAME="Build Number">424</ATTRIBUTE>
<ATTRIBUTE NAME="Install Path">C:\Program Files\Altiris\eXpress\NS 
Client\Software Delivery\Software 
Packages\{01B54EB5-3679-4C73-9E10-E169D5A5EC59}</ATTRIBUTE>
</OBJECT>
</CLASS>
</ASSET>
</INVENTORY>
</RESOURCE>
</RESOURCE_TYPE>
</AEXDATAEXTRACT>

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

In the above xml document I CLASS node corresponds to the table i the database 
and OBJECTS are the records within that table. ATTRIBUTE node contains the 
names of the columns and their values.

As shown in the above example, in the input document there can be same table 
with unequal number of columns. I have to find the table name with maximum 
columns.

I have written the following xsl to do this. I have got the node (CLASS 
NODE)having a node (Row or Record) having maximum column. To get this node 
name i am storing the unique identifier for this node i.e. I am storing 
generate-id for this node. But I am getting generate id for both the CLASS 
node in the above example (I am using xml spy's debugger to go step by step). 
The same construct i am using to find a node with maximum attributes in the 
document. I got only one id for it.

Had i take wrong approach to do this or something else is wrong ?

Second problem is printing the values for the attribtues. I have written the 
match template construct and there I need to print value corresponding to the 
column headers which are stored in the variable. I am not able to write 
suitable construct to do this. Please tell me how do i do this. I have tried 
to use name function to do this but it is giving me invalid Xpath expression.

                                                                      Xsl
====

        
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0">
<xsl:output method="text"/>
<xsl:variable name="mostattributes">
<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()"/><!-- this line has changed! -->
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="mostattributes-node" select="//node()[generate-id() = 
$mostattributes]"/>

<xsl:variable name="maxattClientAgentTable">
<xsl:for-each select="//CLASS">
	<xsl:choose>
		<xsl:when test="normalize-space(@NAME)='Client_Agent'">
			<xsl:for-each select="OBJECT">
				<xsl:sort select="count(ATTRIBUTE)" order="descending"/>
					<xsl:if test="position()=1">
						<xsl:value-of select="generate-id(..)"/><!-- this line has changed! -->
					</xsl:if>
			</xsl:for-each>
		</xsl:when>
	</xsl:choose>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="mostChildattributes-node" select="//node()[generate-id() = 
$maxattClientAgentTable]"/>

<xsl:template match="/">
<xsl:text>RESOURCE_TYPE.GUID,RESOURCE.</xsl:text>
<xsl:for-each select="//node()[generate-id() = $mostattributes]/@*">
<xsl:value-of select="name(.)" ></xsl:value-of>
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
<xsl:text>&#10;</xsl:text>
<xsl:apply-templates select="//RESOURCE"/>
</xsl:template>

<xsl:template match="RESOURCE">
<xsl:variable name="r" select="."/>
<xsl:for-each select="//node()[generate-id() = $mostattributes]/@*">
<!--Note: How do i get the values according to the column names ? I mean I 
will check if the name of the attribues are same then print the value for it 
otherwise print seperator. How do i do this ?<xsl:value-of 
select="normalize-space($r/[name(@)=current()/name(@)])"/> -->
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
<xsl:text>&#10;</xsl:text>
</xsl:template>
</xsl:stylesheet>

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

Thanks in advance for any help.
Waiting for reply.

Regards
Dipesh


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



Current Thread
Keywords