一、XSLT 2.0解决方案:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<screen>
<xsl:for-each select="tokenize(., '\r?\n')">
line: <xsl:sequence select="."/>
</xsl:for-each>
</screen>
</xsl:template>
</xsl:stylesheet>
当此转换应用于提供的 XML 文档时:
<screen>
Volume in drive C is SYSTEM Serial number is 2350:717C
Directory of C:\
10/17/97 9:04 <DIR> bin
10/16/97 14:11 <DIR> DOS
10/16/97 14:40 <DIR> Program Files
10/16/97 14:46 <DIR> TEMP
10/17/97 9:04 <DIR> tmp
10/16/97 14:37 <DIR> WINNT
10/16/97 14:25 119 AUTOEXEC.BAT
2/13/94 6:21 54,619 COMMAND.COM
10/16/97 14:25 115 CONFIG.SYS
11/16/97 17:17 61,865,984 pagefile.sys
2/13/94 6:21 9,349 WINA20.386
</screen>
产生了想要的正确结果(文本节点的每一行都由字符串前置"line: "
):
<screen>
line:
line: Volume in drive C is SYSTEM Serial number is 2350:717C
line: Directory of C:\
line:
line: 10/17/97 9:04 <DIR> bin
line: 10/16/97 14:11 <DIR> DOS
line: 10/16/97 14:40 <DIR> Program Files
line: 10/16/97 14:46 <DIR> TEMP
line: 10/17/97 9:04 <DIR> tmp
line: 10/16/97 14:37 <DIR> WINNT
line: 10/16/97 14:25 119 AUTOEXEC.BAT
line: 2/13/94 6:21 54,619 COMMAND.COM
line: 10/16/97 14:25 115 CONFIG.SYS
line: 11/16/97 17:17 61,865,984 pagefile.sys
line: 2/13/94 6:21 9,349 WINA20.386
line: </screen>
说明:
适当地使用tokenize()
带有第二个参数的函数 RegEx,它允许可选的 CR 位于 NL 字符之前。
二、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:strip-space elements="*"/>
<xsl:template match="text()" name="lines">
<xsl:param name="pText" select="."/>
<xsl:if test="string-length($pText)">
line: <xsl:text/>
<xsl:value-of select=
"substring-before(concat($pText, '
'), '
')"/>
<xsl:call-template name="lines">
<xsl:with-param name="pText" select=
"substring-after($pText, '
')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
当这个 XSLT 1.0 转换应用于同一个 XML 文档(上图)时,会产生所需的结果(文本节点的每一行,前面都带有 string "line: "
):
line:
line: Volume in drive C is SYSTEM Serial number is 2350:717C
line: Directory of C:\
line:
line: 10/17/97 9:04 <DIR> bin
line: 10/16/97 14:11 <DIR> DOS
line: 10/16/97 14:40 <DIR> Program Files
line: 10/16/97 14:46 <DIR> TEMP
line: 10/17/97 9:04 <DIR> tmp
line: 10/16/97 14:37 <DIR> WINNT
line: 10/16/97 14:25 119 AUTOEXEC.BAT
line: 2/13/94 6:21 54,619 COMMAND.COM
line: 10/16/97 14:25 115 CONFIG.SYS
line: 11/16/97 17:17 61,865,984 pagefile.sys
line: 2/13/94 6:21 9,349 WINA20.386
说明:
递归命名模板以提取和输出下一行。停止条件——当字符串长度为零时。
适当使用substring-before()
,substring-after()
和哨兵技术以最小化代码长度和复杂性。