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

[xsl] Re: How to get nodes with maximum attributes ??


Subject: [xsl] Re: How to get nodes with maximum attributes ??
From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx>
Date: Fri, 22 Aug 2003 22:26:39 +0200

> I am trying to get the node with maximum attributes. How do i get that.
Facing

It is not necessary at all to modify the value of a variable in order to
find the maximum (and then the node with the maximum).

Here are two solutions:

<!-- Solution 1 (O(N)) -->
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

  <xsl:template match="/">
    <xsl:call-template name="max">
      <xsl:with-param name="pNodes" select="/*/*"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="max">
    <xsl:param name="pNodes" select="/.."/>
    <xsl:variable name="vnumNodes" select="count($pNodes)"/>
    <xsl:choose>
      <xsl:when test="$vnumNodes &lt; 2">
        <xsl:value-of select="count($pNodes[1]/@*)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:variable name="vHalf" select="$vnumNodes div 2"/>
        <xsl:variable name="max1">
          <xsl:call-template name="max">
            <xsl:with-param name="pNodes"
            select="$pNodes[position() &lt;= $vHalf]"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:variable name="max2">
          <xsl:call-template name="max">
            <xsl:with-param name="pNodes"
            select="$pNodes[position() > $vHalf]"/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:value-of select="$max1 * ($max1 >= $max2)
                             +
                              $max2 * ($max1 &lt; $max2)"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>


<!-- Solution 2 (O(N*log2(N))) but faster in almost all real cases -->
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

  <xsl:template match="/">
    <xsl:call-template name="max">
      <xsl:with-param name="pNodes" select="/*/*"/>
    </xsl:call-template>

  </xsl:template>

  <xsl:template name="max">
    <xsl:param name="pNodes" select="/.."/>

    <xsl:for-each select="$pNodes">
      <xsl:sort select="count(@*)" data-type="number" order="descending"/>
      <xsl:if test="position() = 1">
        <xsl:value-of  select="count(@*)"/>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>


When applied on this source.xml:

<t>
  <e a1="1" a2="2"/>
  <e a1="1" a2="2" a3="3"/>
  <e a1="1" a2="2"/>
  <e a1="1" a2="2"/>
  <e a1="1" a2="2"/>
  <e a1="1" a2="2" a3="3" a4="4"/>
  <e a1="1" a2="2"/>
  <e a1="1" a2="2"/>
  <e a1="1" a2="2"/>
  <e a1="1" a2="2"/>
</t>

the correct result is produced:
4

One can also find a node (or all nodes) having this maximum value -- either
by modifying the above solutions to return a node (the first solution will
need the xxx:node-set() extension) or simply with this XPath expression:

$allNodes[count(@*) = $maxValueFound]



=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL



"Dipesh Khakhkhar" <dkhakhkh@xxxxxxxxxxxxxxx> wrote in message
news:3F4A933B@xxxxxxxxxxxxx
> Hi,
>
> I am trying to get the node with maximum attributes. How do i get that.
Facing
> problem with the usage of xs:variable since that can not be change. I want
to
> get the attribute names in my first line of output.
>
> I want to write something like this.
> <!-- Defining Global variables -->
> xsl:var name=colHeaderForTable1;
> xsl:var name=maxColNoForTable1 select="number(0)"; <!-- Keeping maximum
number
> of attributes for the particular node as zero -->
> xsl:for-each //Table1
> xsl:var name=temp select ="count(no. of columns in this table)";
<! --getting
> column count for the current table -->
>
> <!-- For the firt time this comparision will be true and in the global
> variable i will get names of the attribute name -->
> if (temp > maxColNoForTable1)
> colHeaderForTable1={"Somevalue", "Somevalue",Getting each attribute name
> followed by seperator}
>
> </xsl:for-each>
>
> <!-- In this way I want the names of the attributes for a node having
maximum
> no. of attributes. The problem here is i can not change the variable
value, so
> is there any other way to achieve the same. I have not defined the
variable
> inside for loop since I would need that value in future processing of my
> document.
>
>
>
> Below is the input.
>
>
> Input
> ======
>
> <?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_TYPE>
> </AEXDATAEXTRACT>
>
> ===================================================================
>
> Seekin some help.
> Eagerly waiting for reply. Appreciated.
>
> Regards,
> Dipesh
>
>
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
>
>




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



Current Thread
Keywords