我想在我的XML中每10个字符添加一个新标记<br>
。(不含内部节点)
例如我的输入是:
<main>
01234567890123
<a>
link
</a>
45678901234567901234
</main>
我希望是这样的:
<main>
0123456789<br>0123
<a>
link
</a>
456789<br>012345679<br>01234
</main>
我写了这个函数:
<!-- Add new "HTML Break" Every X chars -->
<xsl:template name="Add-HTML-Break-After-X-Chars">
<xsl:param name="text" />
<xsl:param name="max-length" />
<xsl:choose>
<xsl:when test="string-length($text) > $max-length">
<!-- Show the X length of the text -->
<xsl:copy-of select="substring($text,1,$max-length)" />
<!-- Adding the special tag -->
<br/>
<!-- continue to add the rest of the text -->
<xsl:call-template name="Add-HTML-Break-After-X-Chars">
<xsl:with-param name="text" select="substring($text, $max-length + 1)" />
<xsl:with-param name="max-length" select="$max-length" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- Show the text (length is less then X) -->
<xsl:copy-of select="$text" />
</xsl:otherwise>
</xsl:choose>
问题是,我得到的输出没有内部标签:
<main>
0123456789<br>0123
link
45<br>6789012345<br>67901234
</main>
我使用以下代码来调用模板:
<xsl:call-template name="Add-HTML-Break-After-X-Chars">
<xsl:with-param name="text" select="main" />
<xsl:with-param name="max-length" select="10" />
</xsl:call-template>
我也尝试了"value-of"而不是"copy-of"。
我可以保留这些标签吗?
如果是这样,我如何保留它们并使新标签的"安全"插入?
这在XSLT中很难做到,因为它单独处理每个文本节点,没有从前面的文本节点传递信息。
这里有一个可能的方法:
XSLT 1.0<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="main/text()" name="wrap">
<xsl:param name="text" select="."/>
<xsl:param name="line-length" select="10"/>
<xsl:param name="carry">
<xsl:variable name="lengths">
<xsl:for-each select="preceding-sibling::text()">
<length>
<xsl:value-of select="string-length()"/>
</length>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="sum(exsl:node-set($lengths)/length) mod $line-length"/>
</xsl:param>
<xsl:value-of select="substring($text, 1, $line-length - $carry)"/>
<br/>
<xsl:if test="$carry + string-length($text) > $line-length">
<!-- recursive call -->
<xsl:call-template name="wrap">
<xsl:with-param name="text" select="substring($text, $line-length - $carry + 1)"/>
<xsl:with-param name="carry" select="0"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
当它应用于以下测试输入时:
XML><main>A123456789B123<a>link1</a>456789C123456789D12345678<a>link2</a>9E123456789F1234567</main>
结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<main>A123456789<br/>B123<a>link1</a>456789<br/>C123456789<br/>D12345678<a>link2</a>9<br/>E123456789<br/>F1234567</main>