[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
Hi Michael,
Thank your for your response. I tried to adapt your solution but I don't get it well.
Maybe I didn't understand your algo but this is what I come out :
I supposed nodes param should be node()* typed and the for-each loop should be applied to $nodes, is this correct?
But then I don't understand why using a group-starting-with, then all my level should be one inside the other, which is not really what I want.
My goal is to prevent *orphans* title, that's why I need to group each title with his first-sibling (with conditions as said before).
I do that to simulate the css rule page-break-after:avoid wich doesn't work well with electronic books.
Anyway this is the XSLT :
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/1999/xhtml"
xpath-default-namespace="http://www.w3.org/1999/xhtml"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template name="group">
<xsl:param name="nodes" as="node()*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:variable name="hN" select="concat('h', $level)"/>
<xsl:for-each-group select="$nodes" group-starting-with="*[local-name() = $hN]">
<xsl:choose>
<xsl:when test="local-name(current-group()[1]) = $hN">
<div class="group">
<xsl:apply-templates select="current-group()[1]"/>
<xsl:call-template name="group">
<xsl:with-param name="nodes" select="current-group() except current-group()[1]"/>
<xsl:with-param name="level" select="$level + 1"/>
</xsl:call-template>
</div>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()[1]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
I will trie to add a "group-ending-with" inside the group-starting-with...
Cheers,
Matthieu
Le 18/01/2011 13:36, Michael Kay a icrit :
Re: [xsl] grouping xhtml title with first sibling
Subject: Re: [xsl] grouping xhtml title with first sibling From: Matthieu Ricaud-Dussarget <matthieu.ricaud@xxxxxxxxx> Date: Tue, 18 Jan 2011 14:46:16 +0100 |
Hi Michael,
Thank your for your response. I tried to adapt your solution but I don't get it well.
Maybe I didn't understand your algo but this is what I come out :
I supposed nodes param should be node()* typed and the for-each loop should be applied to $nodes, is this correct?
But then I don't understand why using a group-starting-with, then all my level should be one inside the other, which is not really what I want.
My goal is to prevent *orphans* title, that's why I need to group each title with his first-sibling (with conditions as said before).
I do that to simulate the css rule page-break-after:avoid wich doesn't work well with electronic books.
Anyway this is the XSLT :
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/1999/xhtml"
xpath-default-namespace="http://www.w3.org/1999/xhtml"
>
<xsl:output method="xml" indent="yes"/>
<!--default copy--> <xsl:template match="* | @* | processing-instruction() | comment()"> <xsl:copy copy-namespaces="no"> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template>
<!--keep namespace on top element--> <xsl:template match="html"> <html xmlns="http://www.w3.org/1999/xhtml"> <xsl:apply-templates/> </html> </xsl:template>
<xsl:template match="body"> <xsl:copy copy-namespaces="no"> <xsl:copy-of select="@*"/> <xsl:call-template name="group"> <xsl:with-param name="level" select="1"/> <xsl:with-param name="nodes" select="*"/> </xsl:call-template> </xsl:copy> </xsl:template>
<xsl:template name="group">
<xsl:param name="nodes" as="node()*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:variable name="hN" select="concat('h', $level)"/>
<xsl:for-each-group select="$nodes" group-starting-with="*[local-name() = $hN]">
<xsl:choose>
<xsl:when test="local-name(current-group()[1]) = $hN">
<div class="group">
<xsl:apply-templates select="current-group()[1]"/>
<xsl:call-template name="group">
<xsl:with-param name="nodes" select="current-group() except current-group()[1]"/>
<xsl:with-param name="level" select="$level + 1"/>
</xsl:call-template>
</div>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()[1]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
I will trie to add a "group-ending-with" inside the group-starting-with...
Cheers,
Matthieu
Le 18/01/2011 13:36, Michael Kay a icrit :
You don't need dynamic XPath evaluation for this.
The basic structure you want can be achieved with
<xsl:template name="group">
<xsl:param name="nodes" as="node()"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:for-each-group select="*" group-starting-with="*[local-name() = concat('h', $level)]">
<div>
<xsl:call-template name="group">
<xsl:with-param name="nodes" select="current-group()"/>
<xsl:with-param name="level" select="$level + 1"/>
</xsl:call-template>
</div>
</xsl:for-each-group>
</xsl:template>
and then start the recursion off with level="1". You'll have to modify this slightly to avoid getting a div element for the elements that precede the first hN element at each level.
Michael Kay
Saxonica
-- Matthieu Ricaud IGS-CP Service Livre numirique
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] grouping xhtml title with, Michael Kay | Thread | Re: [xsl] grouping xhtml title with, Michael Kay |
Re: [xsl] grouping xhtml title with, Michael Kay | Date | Re: [xsl] grouping xhtml title with, Michael Kay |
Month |