Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

XSLT - grupowanie następujących po sobie elementów na podstawie atrybutu

36 views
Skip to first unread message

Borys Pogoreło

unread,
Nov 2, 2014, 1:03:19 PM11/2/14
to
Cześć,

Mam nadzieję, że ktoś tu jeszcze żyje...

Problem jest następujący - muszę w XSLT uzyskać efekt taki, że następujące
po sobie elementy, z tą samą wartością określonego atrybutu, w postaci
wyjściowej będą zawarte wewnątrz jednego elementu.

Czyli przykładowo:

<objects>
<object template="a">aaa</object>
<object template="a">aaa</object>
<object template="b">bbb</object>
<object template="a">aaa</object>
</object>

powinno dać na wyjściu:

<wrapper> aaa aaa </wrapper>
bbb
<wrapper> aaa </wrapper>

Póki co (chyba) udało mi się uzyskać ten efekt następującym łamańcem, ale
czy da się to zrobić jakoś prościej?

<xsl:template match="object[@template = 'a']">
<xsl:if test="position() = 1 or preceding-sibling::object[1]/@template !=
'a'">

<wrapper>
<xsl:variable name="pos" select="position()"/>
<xsl:apply-templates select=".|following-sibling::object[@template =
'a' and not(preceding-sibling::object[position() &gt;= $pos and @template
!= 'a'])]" mode="content"/>
</wrapper>

</xsl:if>
</xsl:template>

<xsl:template match="object[@template = 'a']" mode="content">
<!-- ... tutaj wyświetlamy element ... -->
</xsl:template>

--
Borys Pogoreło
borys(#)leszno,edu,pl

Borys Pogoreło

unread,
Nov 2, 2014, 1:44:14 PM11/2/14
to
Dnia Sun, 2 Nov 2014 19:03:10 +0100, Borys Pogoreło napisał(a):

> Póki co (chyba) udało mi się uzyskać ten efekt następującym łamańcem, ale
> czy da się to zrobić jakoś prościej?

... i sam sobie odpowiem: da się. I po co ja tak kombinowałem.

Dla potomnych:

<xsl:template match="object[@template = 'a']">

<xsl:if test="position() = 1 or preceding-sibling::object[1]/@template !=
'a'">

<wrapper>
<xsl:apply-templates select="." mode="content"/>
</wrapper>

</xsl:if>

</xsl:template>

<xsl:template match="object[@template = 'a']" mode="content">

<xsl:variable name="next" select="following-sibling::object[@template =
'a' and position() = 1]"/>

<!-- formatowanie -->

<xsl:if test="$next">
<xsl:apply-templates select="$next" mode="content"/>
</xsl:if>

TOUDIdel

unread,
Nov 7, 2014, 6:38:55 AM11/7/14
to Borys Pogoreło
W dniu 02.11.2014 o 19:44, Borys Pogoreło pisze:
> Dnia Sun, 2 Nov 2014 19:03:10 +0100, Borys Pogoreło napisał(a):
>
>> Póki co (chyba) udało mi się uzyskać ten efekt następującym łamańcem, ale
>> czy da się to zrobić jakoś prościej?
>
> ... i sam sobie odpowiem: da się. I po co ja tak kombinowałem.

No i prościej nie ma co kombinować. Najważniejsze w takim problemie, by
korzystać z osi.

--
td

0 new messages