XSLT problem with single tags

55 views
Skip to first unread message

dwergkees

unread,
May 7, 2006, 1:13:42 PM5/7/06
to xml and xslt
Hi,

Got a litte problem here. I'm trying to create a XSLT file that will do
a transformation from WordML format (MS Word XML format, see
http://rep.oio.dk/Microsoft.com/officeschemas/welcome.htm) to a
reasonably clean (X)HTML format.

(The reason being that, combined with some PHP scripting it should be
possible to store the embedded images, which is pretty neat).

I am, however running into a XSLT problem. An piece of an old version
works like this:

<xsl:template match="w:r">
<xsl:choose>
<xsl:when test=".//w:i">
<i><xsl:apply-templates /></i>
</xsl:when>
<xsl:when test=".//w:b">
<b><xsl:apply-templates /></b>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates />
</xsl:otherwise>
</xsl:choose>
</xsl:template>

This matches the r element (Run element, kind of a default container
thingy). It tests whether the r element contains an i or b element
(meaning of course that the content of that r element is in italic or
bold.) When this is the case, nice html style tags are placed. This
doesn't function properly in the case where an r element contains both
an i and a b element, i.e. when the text is both italic and bold.
Therefore, i changed the code to:

<xsl:template match="w:r">
<xsl:if test=".//w:i">
<i>
</xsl:if>

<xsl:if test=".//w:b">
<b>
</xsl:if>

<xsl:apply-templates />

<xsl:if test=".//w:i">
</i>
</xsl:if>

<xsl:if test=".//w:b">
</b>
</xsl:if>
</xsl:template>

It now tests twice for each style, for the opening tag and for the
closing tag. In principal this works fine, but in practice the xslt
sheet is not well-formed and will not be applied as it contains non
closed tags (the <i> and <b> tags). I've tried to:
- replace the < and > with &lt; and &gt;
- put the tages inside CDATA sections, for example <![CDATA[<i>]]>


However, in both cases the tags of appear as literal text instead of
HTML code.

Any ideas on how to able to insert single open or closing tags in my
HTML code, or another solution to properly nest the <i> and <b>
elements?

TIA

Wilco - Dwergkees - Menge

Joris Gillis

unread,
May 27, 2006, 4:57:16 PM5/27/06
to xml-an...@googlegroups.com
Tempore 19:13:42, die 07/05/2006 AD, hinc in xml-an...@googlegroups.com scripsit dwergkees <wilco...@hotmail.com>:

> <xsl:template match="w:r">
> <xsl:if test=".//w:i">
> <i>
> </xsl:if>
>
> <xsl:if test=".//w:b">
> <b>
> </xsl:if>
>
> <xsl:apply-templates />
>
> <xsl:if test=".//w:i">
> </i>
> </xsl:if>
>
> <xsl:if test=".//w:b">
> </b>
> </xsl:if>
> </xsl:template>
>
> It now tests twice for each style, for the opening tag and for the
> closing tag. In principal this works fine, but in practice the xslt
> sheet is not well-formed and will not be applied as it contains non
> closed tags (the <i> and <b> tags). I've tried to:

> - replace the < and > with < and >


> - put the tages inside CDATA sections, for example <![CDATA[<i>]]>

That's not avery XSL'ish approach.
In XSLT, you create *elements*, not tags.

Here's one way to do it:

(correct the namespace xmlns:w)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:w="specify-the-namespace-here">
<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes"/>

<xsl:template match="w:r">

<xsl:apply-templates select="(w:rPr|w:t)[1]"/>
</xsl:template>

<xsl:template match="w:rPr">
<xsl:apply-templates select="*[1]"/>
</xsl:template>

<xsl:template match="w:rPr/*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="(following-sibling::*|../../w:t)[1]"/>
</xsl:element>
</xsl:template>

</xsl:stylesheet>


--
Joris Gillis (http://users.telenet.be/root-jg/me.html)
Veni, vidi, wiki (http://www.wikipedia.org)

Reply all
Reply to author
Forward
0 new messages