0

I have HTML code in entity form, such as

<zh_tw shortText="">&amp;nbsp;</zh_tw>    

embedded in an XML file. I would for that text to be rendered as HTML when I view the XML text in a browser. I have a simple XSLT created for the XML file to be transformed into a table format, but I don't want the HTML code to display as code.

Here is a sample of the code in XML:

<?xml-stylesheet type='text/xsl' href='Simple.xslt'?>
<Projects>
  <Project>
    <Text Type="surveyitem" SubType="intro" TranslationGroupID="46675">
     <zh_tw shortText="">&amp;nbsp;</zh_tw>
    </Text>
      <Scale Type="scaletext" ScaleTextID="23501">
        <en_us>to translate</en_us>
        <zh_tw>to translate</zh_tw>
      </Scale>
    </Text>
  </Project>
</Projects>

Here is the XSLT I am using:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="html" indent="yes" version="4.0"/>


<xsl:template match="/">

  <html>
  <body>
  <table border="1">
     <tr bgcolor="#9acd32">
        <th>Translation</th>
      </tr>
      <xsl:for-each select="Projects/Project/Text">
        <tr>
          <td><xsl:value-of select="zh_tw"/></td>
       </tr>
      </xsl:for-each>
     <xsl:for-each select="Projects/Project/Text/Scale">
        <tr>
          <td><xsl:value-of select="zh_tw"/></td>
       </tr>
      </xsl:for-each>
    </table>
 </body>
  </html>

  </xsl:template>
</xsl:stylesheet>
j08691
  • 204,283
  • 31
  • 260
  • 272

1 Answers1

0

Using disable-output-escaping is a bad idea. Better is to use a string replacement template as Welbog's solution here.

This XSLT 1.0 style-sheet...

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

<xsl:output method="html" indent="yes" version="4.0"/>

<xsl:template name="string-replace-all">
  <xsl:param name="text"/>
  <xsl:param name="replace"/>
  <xsl:param name="by"/>
  <xsl:choose>
    <xsl:when test="contains($text,$replace)">
      <xsl:value-of select="substring-before($text,$replace)"/>
      <xsl:value-of select="$by"/>
      <xsl:call-template name="string-replace-all">
        <xsl:with-param name="text" select="substring-after($text,$replace)"/>
        <xsl:with-param name="replace" select="$replace"/>
        <xsl:with-param name="by" select="$by"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$text"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template name="replace-entities">
  <xsl:param name="text"/>
  <xsl:call-template name="string-replace-all">
    <xsl:with-param name="text" select="$text" />
    <xsl:with-param name="replace" select="'&amp;nbsp;'" />
    <xsl:with-param name="by" select="'&#160;'" />
  </xsl:call-template>
  <!-- Add more calls to string-replace-all for each entity reference you want to map. -->
</xsl:template>

<xsl:template match="/">
  <html>
  <body>
  <table border="1">
     <tr bgcolor="#9acd32">
        <th>Translation</th>
      </tr>
      <xsl:for-each select="Projects/Project/Text">
        <tr>
          <td>
            <xsl:call-template name="replace-entities">
              <xsl:with-param name="text" select="zh_tw" />
            </xsl:call-template>
          </td>
       </tr>
      </xsl:for-each>
     <xsl:for-each select="Projects/Project/Text/Scale">
        <tr>
          <td>
            <xsl:call-template name="replace-entities">
              <xsl:with-param name="text" select="zh_tw" />
            </xsl:call-template>
          </td>
       </tr>
      </xsl:for-each>
    </table>
 </body>
  </html>

  </xsl:template>
</xsl:stylesheet>

...when applied to your input will yield this html...

<html>
  <body>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Translation</th>
      </tr>
      <tr>
        <td> </td>
      </tr>
      <tr>
        <td>to translate</td>
      </tr>
    </table>
  </body>
</html>

...which will render the middle row as simply as a space. In the listing above the white space between the td tags for the middle row is actually character with code-point 160, not the normal space character. Of course this does not show very well in a code listing.

Some XSLT processors may serialise the nbsb character as &#160; or even as &nbsp;. All these outcomes should be ok, as they mean the same thing to the browser and will all render the same way.

Community
  • 1
  • 1
Sean B. Durkin
  • 12,659
  • 1
  • 36
  • 65