如何在保留包装文本的同时保留数据中的换行符,制表符和空格?
问题描述:
我有XML格式的数据,我想在输出HTML中保留换行符,空格和制表符(所以我不能使用<p>),但我也希望在屏幕的一侧显示换行(所以我不能使用<pre>)。如何在保留包装文本的同时保留数据中的换行符,制表符和空格?
答
我和一个同事(帕特里夏Eromosele)提出了以下解决方案:(有没有更好的解决办法吗?)
<p>
<xsl:call-template name="prewrap">
<xsl:with-param name="text" select="text"/>
</xsl:call-template>
</p>
<xsl:template name="prewrap">
<xsl:param name="text" select="."/>
<xsl:variable name="spaceIndex" select="string-length(substring-before($text, ' '))"/>
<xsl:variable name="tabIndex" select="string-length(substring-before($text, '	'))"/>
<xsl:variable name="lineFeedIndex" select="string-length(substring-before($text, '
'))"/>
<xsl:choose>
<xsl:when test="$spaceIndex = 0 and $tabIndex = 0 and $lineFeedIndex = 0"><!-- no special characters left -->
<xsl:value-of select="$text"/>
</xsl:when>
<xsl:when test="$spaceIndex > $tabIndex and $lineFeedIndex > $tabIndex"><!-- tab -->
<xsl:value-of select="substring-before($text, '	')"/>
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
<xsl:call-template name="prewrap">
<xsl:with-param name="text" select="substring-after($text,'	')"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$spaceIndex > $lineFeedIndex and $tabIndex > $lineFeedIndex"><!-- line feed -->
<xsl:value-of select="substring-before($text, '
')"/>
<br/>
<xsl:call-template name="prewrap">
<xsl:with-param name="text" select="substring-after($text,'
')"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$lineFeedIndex > $spaceIndex and $tabIndex > $spaceIndex"><!-- two spaces -->
<xsl:value-of select="substring-before($text, ' ')"/>
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
<xsl:call-template name="prewrap">
<xsl:with-param name="text" select="substring-after($text,' ')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise><!-- should never happen -->
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
来源:http://jamesjava.blogspot.com/2008/06/xsl-preserving-line-feeds-tabs-and.html
答
真的,我会选择一个它正确地支持这一点,而不是通过更多的XML来争论它。
答
不知道这是否相关,但不是有一个preservespace属性和什么不适用于XML?
答
另一种方法是将所有空间对变为两个非空白空格,将制表符分成四个非空白空格并将所有换行符分成<br>
元素。在XSLT 1.0,我会做:
<xsl:template name="replace-spaces">
<xsl:param name="text" />
<xsl:choose>
<xsl:when test="contains($text, ' ')">
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="substring-before($text, ' ')"/>
</xsl:call-template>
<xsl:text>  </xsl:text>
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="substring-before($text, ' ')" />
</xsl:call-template>
</xsl:when>
<xsl:when test="contains($text, '	')">
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="substring-before($text, '	')"/>
</xsl:call-template>
<xsl:text>    </xsl:text>
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="substring-before($text, '	')" />
</xsl:call-template>
</xsl:when>
<xsl:when test="contains($text, '
')">
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="substring-before($text, '
')" />
</xsl:call-template>
<br />
<xsl:call-template name="replace-spaces">
<xsl:with-param name="text" select="substring-after($text, '
')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
不能够使用尾递归是一个有点痛,但除非文字很长它不应该是一个真正的问题。
XSLT 2.0解决方案将使用<xsl:analyze-string>
。
+0
更正:你的代码中有两个substring-before应该是substring-after。 – MrFox 2009-03-23 11:30:45
我正在使用XSLT将XML转换为HTML,因此不使用编辑器。 – 2008-09-17 20:27:36