|
[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: How to get node with maximum child nodes??
Hi Dipesh ,
I have deviated from your solution and have produced
the following XSL. It illustrates the concept. I hope
you can take some ideas from it. And I also hope I
understood your problem correctly.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan">
<xsl:output method="text" version="1.0"
encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="treefrag1">
<tables>
<xsl:apply-templates select="//CLASS"/>
</tables>
</xsl:variable>
<xsl:variable name="treefrag2">
<tables>
<xsl:for-each
select="xalan:nodeset($treefrag1)/tables/table">
<xsl:sort select="no_of_columns" data-type="number"
order="descending"/>
<table>
<name>
<xsl:value-of select="name"/>
</name>
<no_of_columns>
<xsl:value-of select="no_of_columns"/>
</no_of_columns>
</table>
</xsl:for-each>
</tables>
</xsl:variable>
<xsl:value-of
select="xalan:nodeset($treefrag2)/tables/table[1]/name"
/><xsl:text> : </xsl:text><xsl:value-of
select="xalan:nodeset($treefrag2)/tables/table[1]/no_of_columns"
/>
</xsl:template>
<xsl:template match="//CLASS">
<table>
<name>
<xsl:value-of select="@NAME"/>
</name>
<no_of_columns>
<xsl:value-of
select="count(OBJECT[1]/ATTRIBUTE)"/>
</no_of_columns>
</table>
</xsl:template>
</xsl:stylesheet>
The ideas behind my solution are --
1. I iterate through all the CLASS elements using //
and store its *NAME attribute value* and the no. of
instances of ATTRIBUTE elements in 1st OBJECT
element(I am assuming that all OBJECT elements of a
particular CLASS will have same no. of ATTRIBUTE
elements). I store this result(tree fragment) in a
variable treefrag1.
2. I then iterate through treefrag1 (after converting
it to a nodeset, using Xalan nodeset extension
function) and *sort the records in descending order
based on no of columns*.
3. I then access the 1st row of this sorted result.
This way I am able to find the table with maximum no.
of columns.
Regards,
Mukul
--- Dipesh Khakhkhar <dkhakhkh@xxxxxxxxxxxxxxx> wrote:
> 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>
</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>
</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
>
__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|

Cart








