我想问一下,在XSLT中是否有任何方法可以在某个元素中逐行显示文本并对该行应用某些内容。例如我有
<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>
我想逐行采取并在每一行之前放置空格(括号,连字符等)。
感谢您的帮助: - )
答案 0 :(得分:4)
使用Saxon 9或AltovaXML工具和其他工具支持的XSLT 2.0,您可以使用tokenize
函数,例如。
<xsl:template match="screen">
<xsl:for-each select="tokenize(., '\n')">
<xsl:value-of select="concat('-', .)"/>
</xsl:for-each>
</xsl:template>
使用XSLT 1.0,您可以检查您的处理器是否支持http://www.exslt.org/str/functions/tokenize/index.html等扩展功能。
答案 1 :(得分:3)
<强>予。 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字符之前。
<强> II。 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>
当在同一个XML文档(上面)上应用此XSLT 1.0转换时,将生成所需结果(文本节点的每一行,前面带有字符串"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()
和 sentinel technique 以尽量减少代码长度和复杂性。