I am administrator of a CMS system for publishing web content. Our editors send newsletters out in html format.

Email clients that doesn't understand html display those newsletters as plain text. That means that all the the html tags are displayed as part of the content.

I am working on a solution where I send the content out as plain text for those mail clients that doesn't understand html.

All the content is placed in xml, so that this xml contains both content and html tags bundled together like this:

<Content>
<p>fg f gfd gf ggf gj hk jk
<br />
vbcv vb
<br/>
gdf gf
</p>
<ul>
<li>f gdfg </li>
<li>gfdfgdfg</li>
</ul>
fgfdgfg
</Content>

in my xslt stylesheet I iterate through the node-set like this:

<xsl:apply-templates select="Content" />

<xsl:template match="Content">
<xsl:for-each select="//*">

<xsl:if test="name()='p'">
<xsl:value-of select="."/>
</xsl:if>
<xsl:if test="name()='li'">
* <xsl:value-of select="."/>
</xsl:if>
<xsl:if test="name()='br'">
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:template>

It works fine, but I have one small problem. When I have html tags nested in other html tags and there is also content, like this:

<p>fg f gfd gf ggf gj hk jk<br />vbcv vb<br/>gdf gf</p>

And I use these templates:

<xsl:if test="name()='p'">
<xsl:value-of select="."/>
</xsl:if>

<xsl:if test="name()='br'">
<xsl:text>
</xsl:text>
</xsl:if>

All the content is shown first and then the line breaks. I then end up with a lot of content bundled together and then a lot of line breaks. How can I avoid this??? Please help me?

You should try using separate templates for each element. At the root level, start with

<xsl:template match="/">
  <xsl:apply-templates/>
</xsl:template>

The "apply-templates/" instruction will match whatever template best fits and ignore the rest.

Then for each element, create a new template:

<xsl:template match="p">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="li">
  * <xsl:apply-templates/>
</xsl:template>

<xsl:template match="br">
  <xsl:text>
</xsl:text>
</xsl:template>

There is a "built-in" template for matching text content (text()), so you shouldn't need to call that explicitly.

Finally, if there are elements that you want to remove or ignore, you can create an empty template to catch those:

<xsl:template match="foo"/>

And you can use the pipe character to create joins (in this case think of it as an 'or'):

<xsl:template match="foo | bar  | other "/>

Hope this helps,
John

Thank you very much. Worked like a charm

I am administrator of a CMS system for publishing web content. Our editors send newsletters out in html format.

Email clients that doesn't understand html display those newsletters as plain text. That means that all the the html tags are displayed as part of the content.

I am working on a solution where I send the content out as plain text for those mail clients that doesn't understand html.

All the content is placed in xml, so that this xml contains both content and html tags bundled together like this:

<Content>
<p>fg f gfd gf ggf gj hk jk
<br />
vbcv vb
<br/>
gdf gf
</p>
<ul>
<li>f gdfg </li>
<li>gfdfgdfg</li>
</ul>
fgfdgfg
</Content>

in my xslt stylesheet I iterate through the node-set like this:

<xsl:apply-templates select="Content" />

<xsl:template match="Content">
<xsl:for-each select="//*">

<xsl:if test="name()='p'">
<xsl:value-of select="."/>
</xsl:if>
<xsl:if test="name()='li'">
* <xsl:value-of select="."/>
</xsl:if>
<xsl:if test="name()='br'">
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:template>

It works fine, but I have one small problem. When I have html tags nested in other html tags and there is also content, like this:

<p>fg f gfd gf ggf gj hk jk<br />vbcv vb<br/>gdf gf</p>

And I use these templates:

<xsl:if test="name()='p'">
<xsl:value-of select="."/>
</xsl:if>

<xsl:if test="name()='br'">
<xsl:text>
</xsl:text>
</xsl:if>

All the content is shown first and then the line breaks. I then end up with a lot of content bundled together and then a lot of line breaks. How can I avoid this??? Please help me?

This article has been dead for over six months. Start a new discussion instead.