Subject: Re: nested block elements in xml -> html From: "Michael Beddow" <gll6mb@xxxxxxxxxxxxxxxxxx> Date: Mon, 5 Jun 2000 15:57:39 +0100 |
Jeni, Many thanks for this reply. You were quite right about why this was such a problem: I have nested lists inside the xml <p> elements, so a simple solution doesn't work, and I need something that will cope with the more complex test source you devised. In fact, after Dan's response I stopped thinking of it as an XSL problem and managed to hide the symptoms by using a combination of <div> and <span>s in my html. But I realised that I hadn't got a truly general solution, which I think your approach supplies. And I can see it pointing the way to solving a few other problems that I've been afraid even to acknowledge yet. Michael ------- Michael Beddow University of Leeds UK > In other words, I'm testing with a source of: > > <p> > <em>Emphasised</em> text before lists > <list> > <item>first item, first list</item> > <item>second item, first list</item> > </list> > Text between lists > <list> > <item>first item, second list</item> > <item>second item, second list</item> > </list> > Text after lists > </p> > > After some playing around, the best I can come up with is the following, > though there may be a simpler way. > > First, generate the groups of text and elements that need to be put into > paragraphs together using keys. The following xsl:key element groups > together all children of 'p' that are not called 'list' by indexing them > according to the unique id of the next sibling 'list' element. > > <xsl:key name="content" match="doc/p/node()[name() != 'list']" > use="generate-id(following-sibling::list)" /> > > Now that we have them in groups, given a node we can generate a paragraph > that contains a copy of (to maintain existing HTML styling) all the nodes > in that group. So first, we want to only look at nodes that are (a) the > first node in the paragraph; (b) the first node after a list; or (c) a list > (since we want to process them too!). I could have selected those nodes > that appear first in the keyed groups, but I didn't because this way was > shorter. > > <xsl:template match="p"> > <xsl:apply-templates > select="node()[1] | > node()[name(preceding-sibling::node()[1]) = 'list'] | > list" /> > </xsl:template> > > Then, for those nodes that aren't lists, we want to take them, and all > other nodes in their group, and put them in a paragraph: > > <xsl:template match="p/node()[name() != 'list']"> > <p class="myclass"> > <xsl:apply-templates mode="copy" > select="key('content', generate-id(following-sibling::list))" /> > </p> > </xsl:template> > > <xsl:template match="node()" mode="copy"> > <xsl:copy-of select="." /> > </xsl:template> > > This enables you to keep your existing template matching 'list', which > probably looks something like: > > <xsl:template match="list"> > <ol> > <xsl:for-each select="item"> > <li><xsl:value-of select="." /></li> > </xsl:for-each> > </ol> > </xsl:template> > > I've tested this and it works with SAXON. > > I hope this helps, > > Jeni XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: nested block elements in xml ->, Jeni Tennison | Thread | ANN: Maintenance 4xt, Eric van der Vlist |
Controlling Sort with dynamic value, Brian Burridge | Date | RE: Keys across multilple input fil, Kay Michael |
Month |