XSL Umformung

S

Sascha Kerschhofer

Hi,
ich suche eine Idee, wie man folgendes mit XSL erreichen kann: folgendes XML
Dokument:
<body>
Erster Text<br/>
Zweiter Text<br/>
<em>Dritter</em> Text<br/>
Vierter <u>Text</u><br clear-previous="true"/>

Fünfter Text<br/>

Sechster Text
</body>

Ich will das nun in einzelne Absätze teilen, aber so, dass der Text im
Absatz es immer "kumulativ" wird außer clear-previous ist true (die übrigen
Formatierungen müssen aber erhalten bleiben). Das würde liefern:

<body>
<p>Erster Text</p>
<p>Erster TextZweiterText</p>
<p>Erster TextZweiterText<em>Dritter</em> Text</p>
<p>Vierter <u>Text</u></p>
<p>Vierter <u>Text</u>Fünfter Text</p>
<p>Vierter <u>Text</u>Fünfter TextSechster Text</p>
</body>

Hat jemand eine Idee oder Lösung?

Sascha Kerschhofer
 
J

Joris Gillis

Ich will das nun in einzelne Absätze teilen, aber so, dass der Text im
Absatz es immer "kumulativ" wird außer clear-previous ist true (die
übrigen
Formatierungen müssen aber erhalten bleiben). Das würde liefern:

Hi,

Here you find a working solution.
It uses a combination of a key method and a recursivly called template.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

<xsl:eek:utput method="xml" indent="yes"/>

<xsl:key name="before_br" match="node()[not(self::br)]"
use="generate-id(following-sibling::br[1])"/>

<xsl:template match="body">
<xsl:copy>
<xsl:apply-templates select="br"/>
<xsl:if test="br[last()]/following-sibling::node()">
<p>
<xsl:apply-templates select="br[last()]" mode="copy_tail"/>
<xsl:copy-of select="br[last()]/following-sibling::node()"/>
</p>
</xsl:if>
</xsl:copy>
</xsl:template>

<xsl:template match="br">
<p>
<xsl:if test="not(@clear-previous='true')">
<xsl:apply-templates select="preceding-sibling::br[1]"
mode="copy_tail"/>
</xsl:if>
<xsl:copy-of select="key('before_br',generate-id())"/>
</p>
</xsl:template>

<xsl:template match="br" mode="copy_tail">
<xsl:apply-templates select="preceding-sibling::br[1]" mode="copy_tail"/>
<xsl:copy-of select="key('before_br',generate-id())"/>
</xsl:template>

<xsl:template match="br[@clear-previous='true']" mode="copy_tail">
<xsl:copy-of select="key('before_br',generate-id())"/>
</xsl:template>

</xsl:stylesheet>

regards,
 
S

Sascha Kerschhofer

Thank you Joris,
this works pretty well. Honestly this is a quite interesting but however a
guru-stylesheet and I don't understand exactly how it works. What is the
recursion-rule? Maybe there is a chance to get it explained :).
Unfortunately I had made a mistake in my example since the "new" text group
must be started after a br[@clear-previous="true"]. The example below is
corrected now. So what need to be modified?

For all not-german speaking people here is the actual question:

I need to transform some text that is divided by empty br-elements into
separate paragraphs. Further all separated text fragments must be
progressively collected. Example:

<body>
First Text<br/>
Second Text<br/>
<em>Thrird</em> Text<br/>
Fourth <u>Text</u><br clear-previous="true"/>
Fifth Text<br/>
Sixt Text
</body>

becomes

<body>
<p>First Text</p>
<p>First TextZweiter Text</p>
<p>First TextSecond Text<em>Third</em> Text</p>
<p>First TextSecond Text<em>Third</em> TextFourth <u>Text</u></p>
<p>Fitht Text</p>
<p>Fith TextSixt Text</p>
</body>


Sascha Kerschhofer
 
J

Joris Gillis

Hi,

On Tue, 28 Jun 2005 14:28:54 +0200, Kerschhofer Alexander

Honestly this is a quite interesting but however a guru-stylesheet
It would take a guru to code a guru-stylesheet:D Mine was probably
unintelligable...
and I don't understand exactly how it works. What is the recursion-rule?
The recursion is done via the 'copy_tail' template
Maybe there is a chance to get it explained :).
see the comments below
Unfortunately I had made a mistake in my example since the "new" text group
must be started after a br[@clear-previous="true"]. The example below is
corrected now. So what need to be modified?

In that case it becomes much easier, it was actually the error in your
sample data that made the job challenging.
Here you have a new stylesheet with comments included:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

<xsl:eek:utput method="xml" indent="yes"/>

<xsl:key name="before_br" match="node()[not(self::br)]"
use="generate-id(following-sibling::br[1])"/>
<!-- the key connects all nodes to their first 'br' element
following-sibling -->

<xsl:template match="body">
<xsl:copy>
<xsl:apply-templates select="br"/>
<xsl:if test="br[last()]/following-sibling::node()">
<!-- handle left-over nodes at the body's end-->
<p>
<xsl:apply-templates select="br[last()]" mode="copy_tail"/>
<xsl:copy-of select="br[last()]/following-sibling::node()"/>
</p>
</xsl:if>
</xsl:copy>
</xsl:template>

<xsl:template match="br">
<p>
<xsl:apply-templates select="." mode="copy_tail"/>
<!-- copy the tail of this 'br' node inside a 'p' element-->
</p>
</xsl:template>

<xsl:template match="br" mode="copy_tail">
<!-- continue copying the tail backwards and only stop when the
'clear-previous' attribute is 'true'-->
<xsl:apply-templates
select="preceding-sibling::br[1][not(@clear-previous='true')]"
mode="copy_tail"/>
<xsl:copy-of select="key('before_br',generate-id())"/>
</xsl:template>

</xsl:stylesheet>


regards,
 
J

Joris Gillis

Wow, so you are indeed a guru xsl-transformer...
I actually meant to say that I do not consider myself a guru at all.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,001
Messages
2,570,249
Members
46,846
Latest member
BettinaOsw

Latest Threads

Top