By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
460,022 Members | 1,398 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 460,022 IT Pros & Developers. It's quick & easy.

branching XSLT tree

P: n/a
hello.

All XML and XSLT are processed by preprocessor as a trees.

How can i simply display my XML as some kind of tree.

given xml:

<struct>
<node level="1" no="1">
<node level="2" no="2" />
</node>
<node level="1" no="5">
<node level="2" no="8" />
</node>
</struct>

given xslt:
<xsl:template match="struct">
<html>
<body>
<xsl:for-each select="node">
<xsl:sort select="@level"/>
<blockquote><pre>
<xsl:value-of select="name()"/> <br/>
<xsl:value-of select="@no"/> <br/>
<xsl:value-of select="@level"/>
</pre></blockquote>
</xsl:for-each>
</body>
</html>
</xsl:template>

i'd like with a little help of <blockquote> do indentation
and as a result sth like this:

node 1
node 2
node 3
node 4
node 2
node 1

but my xslt does it linear and the nodes of all levels are in the same
position:
[..]
node 4
node 2
node 1

thanx in advance
greetings R
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.554 / Virus Database: 346 - Release Date: 03-12-20
Jul 20 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Using the first transformation from my answer to your "Looping templates"
question, and editing it a little we get the following:

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

<xsl:template match="/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>

<xsl:template match="*[not(self::node) and node]">
<table border="1">
<tr>
<xsl:apply-templates select="node"/>
</tr>
</table>
</xsl:template>

<xsl:template match="node">
<tr>
<td ><xsl:value-of select="name()"/></td>
<td><xsl:value-of select="@no"/></td>
<xsl:if test="node">
<tr>
<td>&#xA0;&#xA0;&#xA0;</td>
<td>
<table border="1">
<xsl:apply-templates select="node"/>
</table>
</td>
</tr>
</xsl:if>
</tr>
</xsl:template>
</xsl:stylesheet>
When applied on this source.xml:

<struct>
<node level="1" no="1">
<node level="2" no="2" />
<node level="2" no="3">
<node level="3" no="4"/>
</node>
<node level="2" no="5" />
</node>
<node level="1" no="6">
<node level="2" no="7">
<node level="3" no="8"/>
<node level="3" no="9"/>
</node>
<node level="2" no="10" />
<node level="2" no="11" />
</node>
</struct>
the wanted result is produced (as displayed by a browser):

node 1
node 2

node 3
node 4

node 5

node 6
node 7
node 8

node 9

node 10

node 11

Hope this helped.

Dimitre Novatchev.
FXSL developer, XML Insider,

http://fxsl.sourceforge.net/ -- the home of FXSL
Resume: http://fxsl.sf.net/DNovatchev/Resume/Res.html


"Ruthless" <ruthless@NO_SPAM.poczta.onet.pl> wrote in message
news:bs**********@nemesis.news.tpi.pl...
hello.

All XML and XSLT are processed by preprocessor as a trees.

How can i simply display my XML as some kind of tree.

given xml:

<struct>
<node level="1" no="1">
<node level="2" no="2" />
</node>
<node level="1" no="5">
<node level="2" no="8" />
</node>
</struct>

given xslt:
<xsl:template match="struct">
<html>
<body>
<xsl:for-each select="node">
<xsl:sort select="@level"/>
<blockquote><pre>
<xsl:value-of select="name()"/> <br/>
<xsl:value-of select="@no"/> <br/>
<xsl:value-of select="@level"/>
</pre></blockquote>
</xsl:for-each>
</body>
</html>
</xsl:template>

i'd like with a little help of <blockquote> do indentation
and as a result sth like this:

node 1
node 2
node 3
node 4
node 2
node 1

but my xslt does it linear and the nodes of all levels are in the same
position:
[..]
node 4
node 2
node 1

thanx in advance
greetings R
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.554 / Virus Database: 346 - Release Date: 03-12-20


Jul 20 '05 #2

P: n/a
thanks again ;D

greetings R

Użytkownik "Dimitre Novatchev" <dn********@yahoo.com> napisał w wiadomości
news:bs***********@ID-152440.news.uni-berlin.de...
Using the first transformation from my answer to your "Looping templates"
question, and editing it a little we get the following:

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

<xsl:template match="/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>

<xsl:template match="*[not(self::node) and node]">
<table border="1">
<tr>
<xsl:apply-templates select="node"/>
</tr>
</table>
</xsl:template>

<xsl:template match="node">
<tr>
<td ><xsl:value-of select="name()"/></td>
<td><xsl:value-of select="@no"/></td>
<xsl:if test="node">
<tr>
<td>&#xA0;&#xA0;&#xA0;</td>
<td>
<table border="1">
<xsl:apply-templates select="node"/>
</table>
</td>
</tr>
</xsl:if>
</tr>
</xsl:template>
</xsl:stylesheet>
When applied on this source.xml:

<struct>
<node level="1" no="1">
<node level="2" no="2" />
<node level="2" no="3">
<node level="3" no="4"/>
</node>
<node level="2" no="5" />
</node>
<node level="1" no="6">
<node level="2" no="7">
<node level="3" no="8"/>
<node level="3" no="9"/>
</node>
<node level="2" no="10" />
<node level="2" no="11" />
</node>
</struct>
the wanted result is produced (as displayed by a browser):

node 1
node 2

node 3
node 4

node 5

node 6
node 7
node 8

node 9

node 10

node 11

Hope this helped.

Dimitre Novatchev.
FXSL developer, XML Insider,

http://fxsl.sourceforge.net/ -- the home of FXSL
Resume: http://fxsl.sf.net/DNovatchev/Resume/Res.html


"Ruthless" <ruthless@NO_SPAM.poczta.onet.pl> wrote in message
news:bs**********@nemesis.news.tpi.pl...
hello.

All XML and XSLT are processed by preprocessor as a trees.

How can i simply display my XML as some kind of tree.

given xml:

<struct>
<node level="1" no="1">
<node level="2" no="2" />
</node>
<node level="1" no="5">
<node level="2" no="8" />
</node>
</struct>

given xslt:
<xsl:template match="struct">
<html>
<body>
<xsl:for-each select="node">
<xsl:sort select="@level"/>
<blockquote><pre>
<xsl:value-of select="name()"/> <br/>
<xsl:value-of select="@no"/> <br/>
<xsl:value-of select="@level"/>
</pre></blockquote>
</xsl:for-each>
</body>
</html>
</xsl:template>

i'd like with a little help of <blockquote> do indentation
and as a result sth like this:

node 1
node 2
node 3
node 4
node 2
node 1

but my xslt does it linear and the nodes of all levels are in the same
position:
[..]
node 4
node 2
node 1

thanx in advance
greetings R
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.554 / Virus Database: 346 - Release Date: 03-12-20


---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.554 / Virus Database: 346 - Release Date: 03-12-20
Jul 20 '05 #3

P: n/a
I thought about my example and thought about what might happen if e.g.
element node will be inside some other hierarchy.

For instance - i took my doc.xml and created family.xml

I took <node> as <person>. I've created generations, mariages, singles, and
children(mariages) for new recursive generations.

Still does node has its own hierarchy inside generation hierarchy(i hope i
made myself clear ;))

I tried to branch(display) only the <person>

given xml:

<?xml version="1.0" encoding="iso-8859-2"?>
<?xml-stylesheet type="text/xsl" href="style.xsl"?>
<tree>
<generation level="1">
<mariage>
<person>
<first_name>Aaa</first_name>
<last_name>Qwq</last_name>
</person>
<person>
<first_name>Bbb</first_name>
<last_name>aaa</last_name>
</person>
<children>
<generation level="2">
<mariage>
<person>
<first_name>MMM</first_name>
<last_name>qqq</last_name>
</person>
<person>
<first_name>P</first_name>
<last_name>K</last_name>
</person>
<children/>
</mariage>
<single>
<person>
<first_name>P</first_name>
<last_name>ww</last_name>
</person>
</single>
</generation>
</children>
</mariage>
<single>
<person>
<first_name>P</first_name>
<last_name>ww</last_name>
</person>
</single>

</generation>
</tree>

and yours the stylesheet(a bit modified):

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

<xsl:template match="/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>

<xsl:template match="*[not(self::person) and person]">
<table border="1">
<tr>
<xsl:apply-templates select="person"/>
</tr>
</table>
</xsl:template>

<xsl:template match="person">
<tr>
<td ><xsl:value-of select="name()"/></td>
<td><xsl:value-of select="last_name"/></td>
<td><xsl:value-of select="first_name"/></td>
<xsl:if test="person">
<tr>
<td>&#xA0;&#xA0;&#xA0;</td>
<td>
<table border="1">
<xsl:apply-templates select="person"/>
</table>
</td>
</tr>
</xsl:if>
</tr>
</xsl:template>
</xsl:stylesheet>

I tried to display all the persons - but only top generation(level='1') was
displayed

I don't know how to ommit all those unnecessary(from my point of view, as
far as i'm only interested in persons) elements and simply display only
persons as a branching table.

thanks in advance
you already helped me a lot with the understanding the XSLT

greetings R
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.554 / Virus Database: 346 - Release Date: 03-12-20
Jul 20 '05 #4

P: n/a

"Ruthless" <ruthless@NO_SPAM.poczta.onet.pl> wrote in message
news:bs**********@atlantis.news.tpi.pl...
I thought about my example and thought about what might happen if e.g.
element node will be inside some other hierarchy.

For instance - i took my doc.xml and created family.xml

I took <node> as <person>. I've created generations, mariages, singles, and children(mariages) for new recursive generations.

Still does node has its own hierarchy inside generation hierarchy(i hope i
made myself clear ;))

I tried to branch(display) only the <person>

given xml:

<?xml version="1.0" encoding="iso-8859-2"?>
<?xml-stylesheet type="text/xsl" href="style.xsl"?>
<tree>
<generation level="1">
<mariage>
<person>
<first_name>Aaa</first_name>
<last_name>Qwq</last_name>
</person>
<person>
<first_name>Bbb</first_name>
<last_name>aaa</last_name>
</person>
<children>
<generation level="2">
<mariage>
<person>
<first_name>MMM</first_name>
<last_name>qqq</last_name>
</person>
<person>
<first_name>P</first_name>
<last_name>K</last_name>
</person>
<children/>
</mariage>
<single>
<person>
<first_name>P</first_name>
<last_name>ww</last_name>
</person>
</single>
</generation>
</children>
</mariage>
<single>
<person>
<first_name>P</first_name>
<last_name>ww</last_name>
</person>
</single>

</generation>
</tree>

and yours the stylesheet(a bit modified):

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

<xsl:template match="/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>

<xsl:template match="*[not(self::person) and person]">
<table border="1">
<tr>
<xsl:apply-templates select="person"/>
</tr>
</table>
</xsl:template>

<xsl:template match="person">
<tr>
<td ><xsl:value-of select="name()"/></td>
<td><xsl:value-of select="last_name"/></td>
<td><xsl:value-of select="first_name"/></td>
<xsl:if test="person">
<tr>
<td>&#xA0;&#xA0;&#xA0;</td>
<td>
<table border="1">
<xsl:apply-templates select="person"/>
</table>
</td>
</tr>
</xsl:if>
</tr>
</xsl:template>
</xsl:stylesheet>

I tried to display all the persons - but only top generation(level='1') was displayed

I don't know how to ommit all those unnecessary(from my point of view, as
far as i'm only interested in persons) elements and simply display only
persons as a branching table.

thanks in advance
you already helped me a lot with the understanding the XSLT


Dear R,

Yes, this is possible.

I started with a transformation, which produces a nice hierarchical html
display of all elements in the xml tree.

Then I masked all elements, whose name is not the same as the value of a
special xsl:param.

Here's the result:

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

<xsl:param name="pNodeName" select="'person'"/>

<xsl:template match="/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>

<xsl:template match="*">
<tr>
<td >
<xsl:if test="name() = $pNodeName">
<xsl:value-of select="name()"/>
</xsl:if>
<xsl:text> </xsl:text>
</td>
<td>
<xsl:if test="name() = $pNodeName">
<xsl:variable name="vNodeNum">
<xsl:number count="*" level="multiple"/>
</xsl:variable>
<xsl:value-of select="$vNodeNum"/>
</xsl:if>
<xsl:text> </xsl:text>
</td>
<xsl:if test="*">
<tr>
<td>&#xA0;&#xA0;&#xA0;</td>
<td>
<table border="1">
<xsl:apply-templates select="*"/>
</table>
</td>
</tr>
</xsl:if>
</tr>
</xsl:template>
</xsl:stylesheet>
Hope that this helped.
Dimitre Novatchev.
FXSL developer, XML Insider,

http://fxsl.sourceforge.net/ -- the home of FXSL
Resume: http://fxsl.sf.net/DNovatchev/Resume/Res.html
Jul 20 '05 #5

P: n/a
once again thanks

greetings R

Użytkownik "Dimitre Novatchev" <dn********@yahoo.com> napisał w wiadomości
news:bt************@ID-152440.news.uni-berlin.de...

"Ruthless" <ruthless@NO_SPAM.poczta.onet.pl> wrote in message
news:bs**********@atlantis.news.tpi.pl...
I thought about my example and thought about what might happen if e.g.
element node will be inside some other hierarchy.

For instance - i took my doc.xml and created family.xml

I took <node> as <person>. I've created generations, mariages, singles,

and
children(mariages) for new recursive generations.

Still does node has its own hierarchy inside generation hierarchy(i hope i made myself clear ;))

I tried to branch(display) only the <person>

given xml:

<?xml version="1.0" encoding="iso-8859-2"?>
<?xml-stylesheet type="text/xsl" href="style.xsl"?>
<tree>
<generation level="1">
<mariage>
<person>
<first_name>Aaa</first_name>
<last_name>Qwq</last_name>
</person>
<person>
<first_name>Bbb</first_name>
<last_name>aaa</last_name>
</person>
<children>
<generation level="2">
<mariage>
<person>
<first_name>MMM</first_name>
<last_name>qqq</last_name>
</person>
<person>
<first_name>P</first_name>
<last_name>K</last_name>
</person>
<children/>
</mariage>
<single>
<person>
<first_name>P</first_name>
<last_name>ww</last_name>
</person>
</single>
</generation>
</children>
</mariage>
<single>
<person>
<first_name>P</first_name>
<last_name>ww</last_name>
</person>
</single>

</generation>
</tree>

and yours the stylesheet(a bit modified):

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

<xsl:template match="/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>

<xsl:template match="*[not(self::person) and person]">
<table border="1">
<tr>
<xsl:apply-templates select="person"/>
</tr>
</table>
</xsl:template>

<xsl:template match="person">
<tr>
<td ><xsl:value-of select="name()"/></td>
<td><xsl:value-of select="last_name"/></td>
<td><xsl:value-of select="first_name"/></td>
<xsl:if test="person">
<tr>
<td>&#xA0;&#xA0;&#xA0;</td>
<td>
<table border="1">
<xsl:apply-templates select="person"/>
</table>
</td>
</tr>
</xsl:if>
</tr>
</xsl:template>
</xsl:stylesheet>

I tried to display all the persons - but only top generation(level='1')

was
displayed

I don't know how to ommit all those unnecessary(from my point of view, as far as i'm only interested in persons) elements and simply display only
persons as a branching table.

thanks in advance
you already helped me a lot with the understanding the XSLT


Dear R,

Yes, this is possible.

I started with a transformation, which produces a nice hierarchical html
display of all elements in the xml tree.

Then I masked all elements, whose name is not the same as the value of a
special xsl:param.

Here's the result:

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

<xsl:param name="pNodeName" select="'person'"/>

<xsl:template match="/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>

<xsl:template match="*">
<tr>
<td >
<xsl:if test="name() = $pNodeName">
<xsl:value-of select="name()"/>
</xsl:if>
<xsl:text> </xsl:text>
</td>
<td>
<xsl:if test="name() = $pNodeName">
<xsl:variable name="vNodeNum">
<xsl:number count="*" level="multiple"/>
</xsl:variable>
<xsl:value-of select="$vNodeNum"/>
</xsl:if>
<xsl:text> </xsl:text>
</td>
<xsl:if test="*">
<tr>
<td>&#xA0;&#xA0;&#xA0;</td>
<td>
<table border="1">
<xsl:apply-templates select="*"/>
</table>
</td>
</tr>
</xsl:if>
</tr>
</xsl:template>
</xsl:stylesheet>
Hope that this helped.
Dimitre Novatchev.
FXSL developer, XML Insider,

http://fxsl.sourceforge.net/ -- the home of FXSL
Resume: http://fxsl.sf.net/DNovatchev/Resume/Res.html

---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.554 / Virus Database: 346 - Release Date: 03-12-20
Jul 20 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.