xsl-list
[Top] [All Lists]

Re: How to get nodes with maximum attributes ??

2003-08-22 13:26:39
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(_at_)mailbox(_dot_)syr(_dot_)edu> wrote in message
news:3F4A933B(_at_)OrangeMail(_dot_)(_dot_)(_dot_)
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



<Prev in Thread] Current Thread [Next in Thread>