xsl-list
[Top] [All Lists]

[xsl] xsl-grouping two different elements together

2010-03-16 09:43:20
hey all,

i've got another grouping problem. i'm a little stuck where to look for.

given the following structure:

<?xml version="1.0" encoding="UTF-8"?>
<kapitel>
        <abs>first</abs>
        <einschub1>first_ein</einschub1>
        <einschub1>second_ein</einschub1>
        <leerzeile/>
        <einschub1>third_ein</einschub1>
        <abs>second</abs>
        <einschub2>first_ein2</einschub2>
        <abs>end</abs>
</kapitel>

this should transform to:

<?xml version="1.0" encoding="UTF-8"?>
<kapitel>
        <abs>first</abs>
        <einschub typ="1">
                <abs>first_ein</abs>
                <abs>second_ein</abs>
                <leerzeile/>
                <abs>third_ein</abs>
        </einschub>
        <abs>second</abs>
        <einschub typ="2">
                <abs>first_ein2</abs>
        </einschub>
        <abs>end</abs>
</kapitel>

my current xslt is:


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:xs="http://www.w3.org/2001/XMLSchema"; exclude-result-prefixes="xs" version="2.0">
        
        
        <xsl:template match="@*|node()">
                <xsl:copy>
                        <xsl:apply-templates select="@*|node()"/>
                </xsl:copy>
        </xsl:template>
        
        <xsl:template match="kapitel">
                <xsl:element name="kapitel">
                        <xsl:for-each-group select="*" 
group-adjacent="local-name()" >
                                <xsl:choose>
                                        <xsl:when 
test="starts-with(current-grouping-key(),'einschub')">
                                                                <xsl:element 
name="einschub">
<xsl:attribute name="typ" select='replace(local-name(), "[^\d]+", "")'/>
                                                                        <xsl:apply-templates 
select="current-group()"/>
                                                                </xsl:element>
                                        </xsl:when>                             
                          
                                        <xsl:otherwise>
                                                <xsl:apply-templates 
select="current-group()"/>
                                        </xsl:otherwise>
                                </xsl:choose>
                        </xsl:for-each-group>
                </xsl:element>
        </xsl:template>
        
        
        <xsl:template match="einschub1|einschub2">
                <xsl:element name="abs">
                        <xsl:apply-templates/>
                </xsl:element>
        </xsl:template>

</xsl:stylesheet>

but this creates two <einschub typ="1"> container. this makes absolutely sense, but i've no idea how to get the <leerzeile> element into the container.

my only idea is to make a 2 pass solution:
1. rename all <leerzeile> elements with a template
... <xsl:when test="preceding-sibling::*[1][starts-with(local-name(),'einschub')] and following-sibling::*[1][starts-with(local-name(),'einschub')] ">
<xsl:element name="{local-name(preceding-sibling::*[1])}"> ...
2. grouping works.


is there any better/more elegant solution? or ideas where to look for?

thanks in advance,
regards,
gregor

--~------------------------------------------------------------------
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>
--~--