HTML 使用 XSLT 换行的新行
New Lines to HTML Line Breaks Using XSLT
我有以下 XML:
<RichText>
Text
Text
Text
</RichText>
我想使用 XSLT 1.0(2.0,如果我真的必须的话)输出以下 HTML:
<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,' ') 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,' '),' ')"/>
<br/>
<xsl:if test="contains($text,' ')">
<xsl:apply-templates select=".">
<xsl:with-param name="text" select="substring-after($text,' ')"/>
</xsl:apply-templates>
</xsl:if>
<xsl:template>
这输出:
<p><br>
Text<br>
Text<br>
Text<br>
<br></p>
尝试以下脚本:
<?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(., '
')"/>
<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() < last()">
<xsl:text disable-output-escaping="yes"><br/></xsl:text>
</xsl:if>
<xsl:text>
</xsl:text>
</xsl:for-each>
</p>
</xsl:template>
</xsl:transform>
我使用 XSLT 2.0,作为一个更易于编写的版本。
可以使用 XSLT 1.0 重写它,但必须使用等效的
1.0 解决方案:
- 标记化,
- 子序列,
- 和修剪。
对于您的 XSLT 1.0 解决方案,我认为您只需要一些 xsl:if
测试来测试您正在处理的当前行前后是否有非白色 space 文本。
试试这个 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,' '),' ')" />
<xsl:variable name="nextText" select="substring-after($text,' ')"/>
<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,' ')">
<xsl:apply-templates select=".">
<xsl:with-param name="text" select="$nextText"/>
</xsl:apply-templates>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
我有以下 XML:
<RichText>
Text
Text
Text
</RichText>
我想使用 XSLT 1.0(2.0,如果我真的必须的话)输出以下 HTML:
<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,' ') 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,' '),' ')"/>
<br/>
<xsl:if test="contains($text,' ')">
<xsl:apply-templates select=".">
<xsl:with-param name="text" select="substring-after($text,' ')"/>
</xsl:apply-templates>
</xsl:if>
<xsl:template>
这输出:
<p><br>
Text<br>
Text<br>
Text<br>
<br></p>
尝试以下脚本:
<?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(., '
')"/>
<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() < last()">
<xsl:text disable-output-escaping="yes"><br/></xsl:text>
</xsl:if>
<xsl:text>
</xsl:text>
</xsl:for-each>
</p>
</xsl:template>
</xsl:transform>
我使用 XSLT 2.0,作为一个更易于编写的版本。
可以使用 XSLT 1.0 重写它,但必须使用等效的 1.0 解决方案:
- 标记化,
- 子序列,
- 和修剪。
对于您的 XSLT 1.0 解决方案,我认为您只需要一些 xsl:if
测试来测试您正在处理的当前行前后是否有非白色 space 文本。
试试这个 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,' '),' ')" />
<xsl:variable name="nextText" select="substring-after($text,' ')"/>
<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,' ')">
<xsl:apply-templates select=".">
<xsl:with-param name="text" select="$nextText"/>
</xsl:apply-templates>
</xsl:if>
</xsl:template>
</xsl:stylesheet>