如何在仍然换行的同时保留换行符,制表符和数据中的空格?

时间:2020-03-05 18:59:54  来源:igfitidea点击:

我的XML数据中有换行符,空格和制表符,我想保留在输出HTML中(所以我不能使用<p>),但是我还希望在到达屏幕的一侧时换行(所以我不能使用<pre>)。

解决方案

回答

我和一位同事(Patricia 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

回答

确实,我会选择一种能够正确支持此功能的编辑器,而不是通过更多XML来进行编辑。

回答

不知道这是否相关,但是不存在一个XML的keepspace属性和什么吗?

回答

另一种放置方式是,我们要将所有成对的空格都变成两个不间断的空格,将制表符变成四个不间断的空格,并且所有换行符都变成&lt;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解决方案将使用&lt;xsl:analyze-string>