2008-09-17 286 views

回答

0

我和一個同事(帕特里夏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, '&#x09;'))"/>
<xsl:variable name="lineFeedIndex" select="string-length(substring-before($text, '&#xA;'))"/>
<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, '&#x09;')"/>
<xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
<xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
<xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
<xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
<xsl:call-template name="prewrap">
<xsl:with-param name="text" select="substring-after($text,'&#x09;')"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$spaceIndex > $lineFeedIndex and $tabIndex > $lineFeedIndex"><!-- line feed -->
<xsl:value-of select="substring-before($text, '&#xA;')"/>
<br/>
<xsl:call-template name="prewrap">
<xsl:with-param name="text" select="substring-after($text,'&#xA;')"/>
</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">&amp;nbsp;</xsl:text>
<xsl:text disable-output-escaping="yes">&amp;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

0

真的,我會選擇一個它正確地支持這一點,而不是通過更多的XML來爭論它。

+0

我正在使用XSLT將XML轉換爲HTML,因此不使用編輯器。 – 2008-09-17 20:27:36

0

不知道這是否相關,但不是有一個preservespace屬性和什麼不適用於XML?

1

另一種方法是將所有空間對變爲兩個非空白空格,將製表符分成四個非空白空格並將所有換行符分成<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>&#xA0;&#xA0;</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, '&#x9;')"> 
     <xsl:call-template name="replace-spaces"> 
     <xsl:with-param name="text" select="substring-before($text, '&#x9;')"/> 
     </xsl:call-template> 
     <xsl:text>&#xA0;&#xA0;&#xA0;&#xA0;</xsl:text> 
     <xsl:call-template name="replace-spaces"> 
     <xsl:with-param name="text" select="substring-before($text, '&#x9;')" /> 
     </xsl:call-template> 
    </xsl:when> 
    <xsl:when test="contains($text, '&#xA;')"> 
     <xsl:call-template name="replace-spaces"> 
     <xsl:with-param name="text" select="substring-before($text, '&#xA;')" /> 
     </xsl:call-template> 
     <br /> 
     <xsl:call-template name="replace-spaces"> 
     <xsl:with-param name="text" select="substring-after($text, '&#xA;')" /> 
     </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