Meta
I have to do two things:
1.) I want to apply templates for certain nodes (p) that do not follow after a (x).
So for the following example the only node that should be processed should be the first (p) .
XML
<p>example...</p>
<x>example...</x>
<p>example...</p>
<p>example...</p>
<p>example...</p>
<x>example...</x>
<p>example...</p>
<p>example...</p>
2.) I also want to process the contents for all (p) nodes as groups that follow after each (x).
So for the example above the contents that follow after each x should be put into the block element (s. below).
<xsl:template match="x">
<fo:block>
<!-- content from following (p) nodes until the next following (x) -->
</fo:block>
</xsl:template>
Is there a simple way to do this with groups or intersections?
You have not shown any parent element but write a template for that parent:
<xsl:template match="div[x]">
<fo:block>
<xsl:for-each-group select="*" group-starting-with="x">
<xsl:choose>
<xsl:when test="self::x">
<fo:block>
<xsl:copy-of select="current-group()[position() gt 1]"/>
</fo:block>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</fo:block>
</xsl:template>
Sample is at http://xsltransform.net/gWvjQeW .
If you're doing the same thing for all groups of p
and you really don't care about the x
elements, you could do:
<xsl:template match="foo">
<xsl:for-each-group select="p" group-adjacent="self::p">
<fo:block>
<xsl:apply-templates select="current-group()"/>
</fo:block>
</xsl:for-each-group>
</xsl:template>
but if you really did want to do something different for the first p
(or multiple first p
):
<xsl:template match="foo">
<xsl:for-each-group select="p" group-adjacent="self::p">
<xsl:apply-templates select="."/>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="p[empty(preceding-sibling::x)]">
<fo:block font-family="serif">
<xsl:value-of select="current-group()"/>
</fo:block>
</xsl:template>
<xsl:template match="p">
<fo:block>
<xsl:value-of select="current-group()"/>
</fo:block>
</xsl:template>
since current-group()
still works in other templates while you're within an iteration of the xsl:for-each-group
.
Thanks to you I found a working solution.
I created a template for the parent container element (s. below):
<xsl:template match="container">
<xsl:for-each group select="*" group-starting-with="x">
<xsl:choose>
<xsl:when test="self::x">
<xsl:apply-templates select="current-group()[position() = 1]"/>
</xsl:when>
<xsl:otherwise
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
And additionally a template for the x element (s.below):
<xsl:template match="x">
<fo:block>
<xsl:apply-templates select="current-group()[position() gt 1]"/>
</fo:block>
</xsl:template>
Result
Contents are processed in groups if preceding sibling is x; and also regulary if not but not as part of any x group.
These things are quiet hard to describe - Thank you for your patience!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.