Hi Spencer,
You did not specify your version of XSLT. However, since you mention
group by (which is something in SQL, but not an instruction in XSLT, but
for-each-group is quite similar) I assumed XSLT 2. Here's how to do your
document in XSLT 2. Note that I removed the xsl:for-each instruction, I
think you do better with template matching. Also, I inversed the logic:
removing all heads matching 'TOC' (throw-away template). Since you
started out with modes, I used modes too to keep it simple.
The output is: first list items, then the content nodes, this is the
output on your input:
<ul>
<li>Title</li>
<li>Heading 1</li>
<li>Heading 2</li>
</ul>
<h1>Head of document: Title</h1>
<p>text/para: (title) This is a paragraph</p>
<p>text/para: (titlebodl)This is a paragraph</p>
<p>a section: (title, toc)1. Title</p>
<p>a section: (title, toc)2. Title</p>
<h2>head: Heading 1</h2>
<p>text/para: (head1)This is a paragraph</p>
<p>text/para: (head1)This is a paragraph</p>
<h2>head: Heading 2</h2>
<p>text/para: (head2)This is a paragraph</p>
<p>text/para: (head2)This is a chart</p>
And here is the XSLT 2 stylesheet:
<xsl:output indent="yes" />
<xsl:template match="root">
<ul>
<xsl:apply-templates select="*" mode="toc"/>
</ul>
<xsl:for-each-group select="*"
group-starting-with="head[not(contains(., 'TOC'))] |
head_document">
<xsl:apply-templates select="current-group()" />
</xsl:for-each-group>
</xsl:template>
<xsl:template match="head[contains(., 'TOC')]" mode="#all"/>
<xsl:template match="*" mode="toc" />
<xsl:template match="head_document | head" mode="toc">
<li><xsl:value-of select="." /></li>
</xsl:template>
<xsl:template match="head_document">
<h1>Head of document: <xsl:value-of select="." /></h1>
</xsl:template>
<xsl:template match="head">
<h2>head: <xsl:value-of select="." /></h2>
</xsl:template>
<xsl:template match="section">
<p>a section: <xsl:value-of select="." /></p>
</xsl:template>
<xsl:template match="*">
<p>text/para: <xsl:value-of select="." /></p>
</xsl:template>
</xsl:stylesheet>
Cheers,
-- Abel Braaksma
http://www.nuntia.nl
Spencer Tickner wrote:
Hi Group,
I'm wondering if anyone has a slick way of solving this problem. I
have an xml document like:
<root>
<head_document>Title</head_document>
<para>This is a paragraph</para>
<bold_para>This is a paragraph</bold_para>
<head>TOC</head>
<section>1. Title</section>
<section>2. Title</section>
<head>Heading 1</head>
<paragraph_indent>This is a paragraph</paragraph_indent>
<paragraph_outdent>This is a paragraph</paragraph_outdent>
<head>Heading 2</head>
<paragraph>This is a paragraph</paragraph>
<chart>This is a chart</chart>
</root>
Basically I'm making a bunch of html documents from this xml document
and a table of contents. Table of contents is easy (I need to grab the
<head_document> element and skip the <head>TOC</head> element):
<xsl:template match="root" mode="toc">
<ul>
<xsl:for-each select="head_document|head[not(contains(., 'TOC'))]">
<li>Do Something</li>
</xsl:for-each>
</ul>
</xsl:template>
Ok, so that all works great, I now have to do something similar to
above but apply-templates to all the elements that belong with the
heads I want. ie: <head_document> down to <head>, skip
<head>TOC</head>, next <head> element down to the next <head> element,
repeat.
Any ideas on how to do this would be very helpful. I thought group-by
would probably be the answer but so far my research hasn't turned up
anything.
Thanks,
Spencer
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--