使用XSLT的HTML换行新行

时间:2017-05-22 16:07:28

标签: html xml xslt line-breaks

我有以下XML:

<RichText>
    Text
    Text
    Text
</RichText>

我想使用XSLT 1.0输出以下HTML(如果我真的需要,则为2.0):

<p>
    Text<br/>
    Text<br/>
    Text
</p>

我尝试过使用以下接近的XSL:

<xsl:template match="text()">
  <xsl:param name="text" select="."/>

  <!-- Because we would rely on $text containing a line break when using 
      substring-before($text,'&#10;') and the last line might not have a
      trailing line break, we append one before doing substring-before().  -->
  <xsl:value-of select="substring-before(concat($text,'&#10;'),'&#10;')"/>
  <br/>

  <xsl:if test="contains($text,'&#10;')">
    <xsl:apply-templates select=".">
      <xsl:with-param name="text" select="substring-after($text,'&#10;')"/>
    </xsl:apply-templates>
  </xsl:if>
<xsl:template>

输出:

<p><br>                  
    Text<br>                  
    Text<br>                  
    Text<br>
<br></p>

2 个答案:

答案 0 :(得分:3)

对于您的XSLT 1.0解决方案,我认为您需要的只是一些xsl:if测试来测试您正在处理的当前行之前和之后是否存在非空白文本。

试试这个XSLT

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

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

<xsl:template match="text()">
   <xsl:param name="text" select="."/>

   <xsl:variable name="startText" select="substring-before(concat($text,'&#10;'),'&#10;')" />
   <xsl:variable name="nextText" select="substring-after($text,'&#10;')"/>
   <xsl:if test="normalize-space($startText)">
       <xsl:value-of select="$startText"/>
      <xsl:if test="normalize-space($nextText)">
         <br />
      </xsl:if>
   </xsl:if>

   <xsl:if test="contains($text,'&#10;')">
      <xsl:apply-templates select=".">
         <xsl:with-param name="text" select="$nextText"/>
      </xsl:apply-templates>
   </xsl:if>
</xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

尝试以下脚本:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

  <xsl:template match="RichText">
    <p>
      <xsl:variable name="txt" select="tokenize(., '&#xA;')"/>
      <xsl:variable name="len" select="count($txt)"/>
      <xsl:for-each select="subsequence($txt, 2, $len - 2)">
        <xsl:value-of select="replace(replace(.,'\s+$',''),'^\s+','')"/>
        <xsl:if test="position() &lt; last()">
          <xsl:text disable-output-escaping="yes">&lt;br/&gt;</xsl:text>
        </xsl:if>
        <xsl:text>&#xA;</xsl:text>
      </xsl:for-each>
    </p>
  </xsl:template>

</xsl:transform>

我使用XSLT 2.0作为更简单的版本来编写。

可以使用XSLT 1.0重写它,但必须使用等效的 1.0 解决方案:

  • 标记化,
  • 子序列,
  • 和修剪。