[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Nodes get new IDs in function?

Subject: Re: Nodes get new IDs in function?
From: "Imsieke, Gerrit, le-tex" <gerrit.imsieke@xxxxxxxxx>
Date: Sat, 10 Apr 2010 17:15:18 +0200
Re:  Nodes get new IDs in function?
On 09.04.2010 11:16, Martynas Jusevicius wrote:
Thanks all for pointing out the xsl:copy-of, now it works like a charm.

As for the grouping approach, I'm considering it, but I can't see why
it's so much better? Performance wise? But it's using recursion as

If the task is to extract only the ToC, it isn't much better. If the task was to hierarchize the whole document, for-each-group may prove less cumbersome than collecting nodes between headings.

Maybe we can agree that for this problem, it is a matter of personal programming style.

I think after I introduced parent-heading() function, my solution
became quite elegant. It's also convenient to have this function in
other situations.

Of course.

Another question is, what is the desired output. You start at level 1, what if there are no h1 elements?

Just change h1 to h5 or whatever in the input data and see the results.

Also, in your solution<li class="level4"><p>Attribution</p></li>  gets
nested in an additional<ul>, which I think is unnecessary. In my
version, it gets flattened to the same level as<li class="level3">.

I'm using the same approach not only for<ul>  list in XHTML, but NCX
table of contents as well. In Adobe Digital Editions, all top-level
headings are collapsed by default (children not shown until clicked),
so having empty nesting elements is not really a good idea.

You are right, your nesting model is better suited for NCX generation.

But of course there's a for-each-group solution to this nesting problem ("if your only tool is a hammer, every problem looks like a nail" -- for-each-group being my hammer):

<?xml version="1.0" encoding="utf-8"?>
  exclude-result-prefixes="my xs"

<xsl:output method="xml" indent="yes" />

  <xsl:template match="/">

  <xsl:template match="body">
      <xsl:sequence select="my:hierarchize-toc(*)" />

<xsl:function name="my:hierarchize-toc" as="element(*)*">
<xsl:param name="nodes" as="element(*)*" />
<xsl:for-each-group select="$nodes"
my:hlevel(.) le min(
for $ph in (
intersect $nodes[my:isHeading(.)]
return my:hlevel($ph),
<xsl:if test="my:isHeading(.)">
<li class="level{my:hlevel(.)}">
<p><xsl:copy-of select="node()" /></p>
<xsl:variable name="subtoc"
select="my:hierarchize-toc(current-group()[position() gt 1])" />
<xsl:if test="$subtoc/*">
<xsl:sequence select="$subtoc" />

  <xsl:function name="my:isHeading" as="xs:boolean">
    <xsl:param name="elt" as="element(*)" />
    <xsl:value-of select="matches(local-name($elt), '^h\d$')" />

<xsl:function name="my:hlevel" as="xs:double">
<xsl:param name="elt" as="element(*)" />
<xsl:value-of select="number(replace(local-name($elt), '^h(\d)$', '$1'))" />



P.S.: I seem to use at least one other tool on a regular basis than just for-each-group: regex functions. You use substring-after which is absolutely adequate there. replace may be considered as overkill. Also a matter of personal preference.

P.P.S.: ToC creation and XHTML splitting will get tougher if you permit <div>s in the XHTML where
- single headings,
- headings together with a section's introductory content, or
- whole sections
are present within these possibly nested divs.

Current Thread


Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
First Name
Last Name
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.