XSL 旨在将 XML 转换为 XML,但是您可以转换文件吗?
line1
line 2 -- foo
line 3
进入
<ol>
<li>line1</li>
<li>line 2 -- foo</li>
<li>line 3</li>
</ol>
只使用 XSLT?
这在 XSLT 2.0 中很简单,在 XSLT 1.0 中也不难:
一、XSLT 1.0 解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<ol>
<xsl:apply-templates/>
</ol>
</xsl:template>
<xsl:template match="text()" name="linesToLi">
<xsl:param name="pText" select="."/>
<xsl:if test="string-length($pText) > 0">
<xsl:variable name="vthisLine" select=
"substring-before(concat($pText, '
'), '
')"/>
<li><xsl:value-of select="$vthisLine"/></li>
<xsl:call-template name="linesToLi">
<xsl:with-param name="pText" select="substring-after($pText, '
')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
当此转换应用于以下 XML 文档(提供的文本,包装到单个顶部元素中,以成为格式良好的 XML 文档)时:
<t>line1
line 2 -- foo
line 3</t>
产生了想要的正确结果:
<ol>
<li>line1</li>
<li>line 2 -- foo</li>
<li>line 3</li>
</ol>
二、XSLT 2.0 解决方案:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vText" as="xs:string">
line1
line 2 -- foo
line 3
</xsl:variable>
<xsl:template match="/">
<ol>
<xsl:for-each select=
"tokenize($vText, '\r?\n')[normalize-space()]">
<li><xsl:sequence select="."/></li>
</xsl:for-each>
</ol>
</xsl:template>
</xsl:stylesheet>
当将此转换应用于任何 XML 文档(未使用)时,将产生所需的正确结果:
<ol>
<li> line1</li>
<li> line 2 -- foo</li>
<li> line 3</li>
</ol>
请注意:
使用 XSLT 2.0 函数unparsed-text()
,我们可以将任何文本文件作为字符串处理,并使用上述代码将其拆分为行。
更准确地说,我们将使用这样的东西:
tokenize(unparsed-text($vSomeUrl), '\r?\n')[normalize-space()]
不幸的是,XSLT 1 没有有效的字符串处理和解析工具,因此它并不真正适合这样的任务(尽管它是可能的)。
在 XSLT 2 中,这种情况发生了变化。例如,请参阅有关 XSLT 2 文本解析的这篇论文。