473,789 Members | 1,966 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

search for maximum hierarchy

Dear All,

may be some of you can help me with an XSLT example how to solve the
following challange.
For the XML below I want to find out the maximum hierarchy level for a
specific element in my XSLT. The result for the example (searching for
<A/>) should be 4 as the element A is nested 4 times maximum.
I guess I have to use somehow the count function with 'following::A'
axes. But I could not get that to work yet.

Thanks a lot for your help
Rolf

<ROOT>
<A>
<A>
<B>
<C>
<A/> nested up to 3
</C>
</B>
</A>
<A>
<B>
<C>
<A>
<A/> nested up to 4
</A>
<C>
</B>
</A>
</A>
</ROOT>
Jul 20 '05 #1
10 2107
Ke*****@t-online.de (KemperR) writes:
may be some of you can help me with an XSLT example how to solve the
following challange.
For the XML below I want to find out the maximum hierarchy level for a
specific element in my XSLT. The result for the example (searching for
<A/>) should be 4 as the element A is nested 4 times maximum.
I guess I have to use somehow the count function with 'following::A'
axes. But I could not get that to work yet.


Hmmm. I found this surprisingly tricky to do. The solution looks
complex, but the bulk of it is just a recursive template for finding
the maximum of a list of numbers.

This does the job:

----XML---- (your xml corrected)
<ROOT>
<A>
<A>
<B>
<C>
<A/>
</C>
</B>
</A>
<A>
<B>
<C>
<A>
<A/>
</A>
</C>
</B>
</A>
</A>
</ROOT>

----XSL---
<xsl:styleshe et
version="1.0"
xmlns:xsl="http ://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<xsl:call-template name="max">
<xsl:with-param name="data">
<!-- We construct a list of local-maximum tree-depths -->
<xsl:for-each select="//*[not(child::*)]">
<xsl:value-of select="count(a ncestor::*)"/>
<xsl:text>:</xsl:text>
</xsl:for-each>
</xsl:with-param>
<xsl:with-param name="max" select="0"/>
</xsl:call-template>
</xsl:template>

<xsl:template name="max">
<xsl:param name="data"/>
<xsl:param name="max"/>
<xsl:choose>
<xsl:when test="$data">
<xsl:variable name="current"
select="number( substring-before($data,': '))"/>
<xsl:call-template name="max">
<xsl:with-param name="data"
select="substri ng-after($data,':' )"/>
<xsl:with-param name="max">
<xsl:choose>
<xsl:when test="$current> $max">
<xsl:value-of select="$curren t"/>
</xsl:when>
<xsl:otherwis e>
<xsl:value-of select="$max"/>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwis e>
<xsl:value-of select="$max"/>
</xsl:otherwise>
</xsl:choose>

</xsl:template>

</xsl:stylesheet>

----Ouput----
<?xml version="1.0"?>
6
If you want to get "4" (for your definition of nesting) then change
the line
<xsl:value-of select="$max"/>
to
<xsl:value-of select="$max - 2"/>

Ben
--
Ben Edgington
Mail to the address above is discarded.
Mail to ben at that address might be read.
http://www.edginet.org/
Jul 20 '05 #2
Ben Edgington <us****@edginet .org> writes:
Ke*****@t-online.de (KemperR) writes:
may be some of you can help me with an XSLT example how to solve the
following challange.
For the XML below I want to find out the maximum hierarchy level for a
specific element in my XSLT. The result for the example (searching for
<A/>) should be 4 as the element A is nested 4 times maximum.
I guess I have to use somehow the count function with 'following::A'
axes. But I could not get that to work yet.


Hmmm. I found this surprisingly tricky to do. The solution looks
complex, but the bulk of it is just a recursive template for finding
the maximum of a list of numbers.


Now I've actually read your question here's a slightly amended
stylesheet that does what you want 8^). I've only changed the two
XPath expressions near the top to use 'A' instead of '*', and added
one to the output of $max (so that the current 'A' element is included
in the count).

<xsl:styleshe et version="1.0" xmlns:xsl="http ://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">

<xsl:call-template name="max">
<xsl:with-param name="data">
<xsl:for-each select="//A[not(child::*)]">
<xsl:value-of select="count(a ncestor::A)"/>
<xsl:text>:</xsl:text>
</xsl:for-each>
</xsl:with-param>
<xsl:with-param name="max" select="0"/>
</xsl:call-template>
</xsl:template>

<xsl:template name="max">
<xsl:param name="data"/>
<xsl:param name="max"/>
<xsl:choose>
<xsl:when test="$data">
<xsl:variable name="current"
select="number( substring-before($data,': '))"/>
<xsl:call-template name="max">
<xsl:with-param name="data"
select="substri ng-after($data,':' )"/>
<xsl:with-param name="max">
<xsl:choose>
<xsl:when test="$current> $max">
<xsl:value-of select="$curren t"/>
</xsl:when>
<xsl:otherwis e>
<xsl:value-of select="$max"/>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwis e>
<xsl:value-of select="$max+1"/>
</xsl:otherwise>
</xsl:choose>

</xsl:template>

</xsl:stylesheet>

--
Ben Edgington
Mail to the address above is discarded.
Mail to ben at that address might be read.
http://www.edginet.org/
Jul 20 '05 #3
Ben Edgington wrote:
Hmmm. I found this surprisingly tricky to do. The solution looks
complex, but the bulk of it is just a recursive template for finding
the maximum of a list of numbers.


Yes, this is not as easy as it looks at first sight.
An interesting example because it puts XSL's mechanisms
to the test. Here is a solution in xmlgawk which I
find much more readable than XSL.

# depth.awk
# Reads an XML document from standard input and
# prints a count value to standard output. The
# count value tells us how deep each kind of
# element is nested inside each other, neglecting
# nesting levels of other elements.
# comp.text.xml 2004-09-09
# JK 2004-09-09

BEGIN { XMLMODE=1 }

# For each element, increase the depth and find
# the maximum of the nesting depths for each element.
XMLSTARTELEM {
nest[XMLSTARTELEM] ++
if (nest[XMLSTARTELEM] > maxdepth[XMLSTARTELEM])
maxdepth[XMLSTARTELEM] = nest[XMLSTARTELEM]
}

# When leaving an element, decrease nesting depth.
XMLENDELEM {
nest[XMLENDELEM] --
}

# Print maximum depth for each kind of element.
END {
for (elem in maxdepth)
print elem, ":", maxdepth[elem]
}
This is the result for the XML data given in your
corrected version:

A : 4
B : 1
C : 1
ROOT : 1

Jul 20 '05 #4
Hi,

Using <xsl:for-each> and sorting method of finding a max, something like...

<?xml version="1.0"?>
<xsl:styleshe et version="1.0"
xmlns:xsl="http ://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:variable name="max-A">
<xsl:for-each select="//A">
<xsl:sort select="count(. | ancestor::A)" data-type="number"
order="descendi ng"/>
<xsl:if test="position( ) = 1">
<xsl:value-of select="count(. | ancestor::A)"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:text>Max nesting of &lt;A&gt; is: </xsl:text>
<xsl:value-of select="$max-A"/>
</xsl:template>
</xsl:stylesheet>

Using recursion, something like...

<?xml version="1.0"?>
<xsl:styleshe et version="1.0"
xmlns:xsl="http ://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:template match="/">
<xsl:variable name="max-A">
<xsl:apply-templates select="(//A)[1]"/>
</xsl:variable>
<xsl:text>Max nesting of &lt;A&gt; is: </xsl:text>
<xsl:value-of select="$max-A"/>
</xsl:template>

<xsl:template match="A">
<xsl:param name="max" select="0"/>
<xsl:variable name="this-max" select="count(. | ancestor::A)"/>
<xsl:variable name="new-max" select="($max * number($this-max &lt;= $max))
+ ($this-max * number($this-max &gt; $max))"/>
<xsl:choose>
<xsl:when test="following ::A | descendant::A">
<xsl:apply-templates select="(follow ing::A | descendant::A)[1]">
<xsl:with-param name="max" select="$new-max"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwis e>
<xsl:value-of select="$new-max"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
HTH
Marrow
http://www.marrowsoft.com - home of Xselerator (XSLT IDE and debugger)
http://www.topxml.com/Xselerator
"KemperR" <Ke*****@t-online.de> wrote in message
news:90******** *************** ***@posting.goo gle.com...
Dear All,

may be some of you can help me with an XSLT example how to solve the
following challange.
For the XML below I want to find out the maximum hierarchy level for a
specific element in my XSLT. The result for the example (searching for
<A/>) should be 4 as the element A is nested 4 times maximum.
I guess I have to use somehow the count function with 'following::A'
axes. But I could not get that to work yet.

Thanks a lot for your help
Rolf

<ROOT>
<A>
<A>
<B>
<C>
<A/> nested up to 3
</C>
</B>
</A>
<A>
<B>
<C>
<A>
<A/> nested up to 4
</A>
<C>
</B>
</A>
</A>
</ROOT>

Jul 20 '05 #5
Dear Ben,

thanks for the code !!

It works fine, but I'm really surprised how complex it is to get this
actually easy information.

Rolf

Ben Edgington <us****@edginet .org> wrote in message news:<87******* *****@edginet.o rg>...
Ben Edgington <us****@edginet .org> writes:
Ke*****@t-online.de (KemperR) writes:
may be some of you can help me with an XSLT example how to solve the
following challange.
For the XML below I want to find out the maximum hierarchy level for a
specific element in my XSLT. The result for the example (searching for
<A/>) should be 4 as the element A is nested 4 times maximum.
I guess I have to use somehow the count function with 'following::A'
axes. But I could not get that to work yet.


Hmmm. I found this surprisingly tricky to do. The solution looks
complex, but the bulk of it is just a recursive template for finding
the maximum of a list of numbers.


Now I've actually read your question here's a slightly amended
stylesheet that does what you want 8^). I've only changed the two
XPath expressions near the top to use 'A' instead of '*', and added
one to the output of $max (so that the current 'A' element is included
in the count).

<xsl:styleshe et version="1.0" xmlns:xsl="http ://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">

<xsl:call-template name="max">
<xsl:with-param name="data">
<xsl:for-each select="//A[not(child::*)]">
<xsl:value-of select="count(a ncestor::A)"/>
<xsl:text>:</xsl:text>
</xsl:for-each>
</xsl:with-param>
<xsl:with-param name="max" select="0"/>
</xsl:call-template>
</xsl:template>

<xsl:template name="max">
<xsl:param name="data"/>
<xsl:param name="max"/>
<xsl:choose>
<xsl:when test="$data">
<xsl:variable name="current"
select="number( substring-before($data,': '))"/>
<xsl:call-template name="max">
<xsl:with-param name="data"
select="substri ng-after($data,':' )"/>
<xsl:with-param name="max">
<xsl:choose>
<xsl:when test="$current> $max">
<xsl:value-of select="$curren t"/>
</xsl:when>
<xsl:otherwis e>
<xsl:value-of select="$max"/>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwis e>
<xsl:value-of select="$max+1"/>
</xsl:otherwise>
</xsl:choose>

</xsl:template>

</xsl:stylesheet>

Jul 20 '05 #6
Rolf Kemper wrote:
It works fine, but I'm really surprised how complex it is to get this
actually easy information.


The complexity comes mostly from the kind of
tool you choose (XSL). There are tools capable
of solving the problem in a more evident way.
I have posted an easier and more general solution.

If the problem to solve was to open a can of
Coca Cola, and your only tool was a hammer,
you would certainly be prepared to face some mess.
Jul 20 '05 #7
KemperR <Ke*****@t-online.de> wrote:
Dear All,

may be some of you can help me with an XSLT example how to solve the
following challange.
For the XML below I want to find out the maximum hierarchy level for a
specific element in my XSLT. The result for the example (searching for
<A/>) should be 4 as the element A is nested 4 times maximum.
I guess I have to use somehow the count function with 'following::A'
axes. But I could not get that to work yet.

Thanks a lot for your help
Rolf

<ROOT>
<A>
<A>
<B>
<C>
<A/> nested up to 3
</C>
</B>
</A>
<A>
<B>
<C>
<A>
<A/> nested up to 4
</A>
<C>
</B>
</A>
</A>
</ROOT>

You had XSL and xmlgawk solution. Here is Bash shell solution:

start () { # Usage: start tag att=value ...
count=`echo ${XML_ELEMENT_S TACK[*]|/$1} | wc -w`
[[ count -gt $1 ]] && eval $1=`echo $count`
}
xml -s start "<ROOT>...</ROOT>"
declare -p A B C

Explanation:
- ${...|/glob} returns all array element matching 'glob' pattern.
In this case, 'A', 'B', 'C'.
- if count is greater than previous value, set variable 'A', 'B', or
'C' to that value. This is similar to testing for "max".
- `echo $count` is needed to strip leading whitespaces put there by
'wc -w'.

Ref:
http://freshmeat.net/projects/bashdiff/
http://home.eol.ca/~parkw/index.html#xml
help xml

--
William Park <op**********@y ahoo.ca>
Open Geometry Consulting, Toronto, Canada
Jul 20 '05 #8


A shorter, if not necessarily more efficient version os:
<xsl:styleshe et xmlns:xsl="http ://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:for-each select="//A">
<xsl:sort select="-count(ancestor: :A)" data-type="number" />
<xsl:if test="position( )=1">
<xsl:value-of select="count(a ncestor-or-self::A)"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

which gives 4 on the originally posted example.

David
Jul 20 '05 #9
William Park wrote:
You had XSL and xmlgawk solution. Here is Bash shell solution:

start () { # Usage: start tag att=value ...
count=`echo ${XML_ELEMENT_S TACK[*]|/$1} | wc -w`
[[ count -gt $1 ]] && eval $1=`echo $count`
}
xml -s start "<ROOT>...</ROOT>"
declare -p A B C
Very short indeed. But a bit cryptic.
Explanation:
- ${...|/glob} returns all array element matching 'glob' pattern.
In this case, 'A', 'B', 'C'.
This is a very powerful feature that is missing in xmlgawk.
In xmlgawk an explicite loop is needed.
- `echo $count` is needed to strip leading whitespaces put there by
'wc -w'.


The descendents of the Bourne shell are not really first choice
for arithmetic applications.
Jul 20 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
10536
by: JP SIngh | last post by:
Hi There I am creating a search page and need help writing the code to build the sql string. I have 3 fields on the main page which a user can choose to enter search terms in any of the 3 fields. My question is how do I write the logic so it only includes the fields in the search criteria where the user has entered anything.
11
4234
by: Petre Huile | last post by:
I have designed a site for a client, but they have hired an internet marketing person to incrase their search engine ranking and traffic. He wants to put extra-large fonts on every page which will make the design looks a bit rediculous. He also said that the big text cannot be hidden. I am just trying to find a compromise. Here are the questions: (1) Is it true that a page with an <H1> tag and very big font size will make a search...
2
2477
by: Zambo via SQLMonster.com | last post by:
Hi! We have Sql Server 2000 in our server (NT 4). Our database have now about +350.000 rows with information of images. Table have lot of columns including information about image name, keywords, location, price, color mode etc. So our database don?t include the images itself, just a path to the location of every image. Keywords -field have data for example like this: cat,animal,pet,home,child with pet,child. Now our search use Full-Text...
83
5970
by: D. Dante Lorenso | last post by:
Trying to use the 'search' in the docs section of PostgreSQL.org is extremely SLOW. Considering this is a website for a database and databases are supposed to be good for indexing content, I'd expect a much faster performance. I submitted my search over two minutes ago. I just finished this email to the list. The results have still not come back. I only searched for: SECURITY INVOKER
38
6943
by: Alan | last post by:
I want to change a 3 digits integer to characters, how can i do that? the 3 digits integer maybe 123, 23 or 3 I want to change the integer to "123", " 23" or " 3" thx
4
9020
by: Tarique Jawed | last post by:
Alright I needed some help regarding a removal of a binary search tree. Yes its for a class, and yes I have tried working on it on my own, so no patronizing please. I have most of the code working, even the removal, I just don't know how to keep track of the parent, so that I can set its child to the child of the node to be removed. IE - if I had C / \ B D
8
3475
by: ignatova | last post by:
Hello, I have been using IBM Net Search Extender to perform full text searches on text columns in relational tables in DB2 without any problems until now. However it doesn't seam to function properly for text indexes created on attributes of typed tables. Here are the issued commands: //create UDT db2 CREATE TYPE CompMetadata_T AS (dummy Integer,Text CLOB(100K),
5
8363
by: samoore33 | last post by:
I use the code below to return rows matching the state in the theState variable. I want to know if it is possible to search through the DataRow that I am returning with the search. I understand that that creates a DataRow Array. I searched through group postings and found where Cor had said something about bulding the DataTable back, not sure what that meant of if I could use it with this, but any help would be appreciated. Dim t As...
0
2463
by: passion | last post by:
"Specialized Search Engines" along with Google Search Capability (2 in 1): http://specialized-search-engines.blogspot.com/ Billions of websites are available on the web and plenty of extremely good search engines are there like Google, Yahoo and Live to name few of them. Though this search engines have extremely efficient, complex and beautiful algorithms designed by gems of the industry, but still they may not deliver best results for...
0
9656
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10374
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9969
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8995
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7519
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6750
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5539
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4076
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3677
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.