Reputation: 103
I'd like to ask if there is any way in XSLT to take line by line of text in some element and apply something to that line. For example i have
<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>
and I would like to take line by line and put white space (bracket, hyphen etc.) before every line.
Thank you for any help :-)
Upvotes: 2
Views: 5005
Reputation: 243479
I. XSLT 2.0 solution:
<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>
when this transformation is applied on the provided XML document:
<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>
the wanted, correct result (each line of the text node is prepended by the string "line: "
) is produced:
<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>
Explanation:
Appropriate use of the tokenize()
function with second argument a RegEx that allows an optional CR to precede the NL character.
II. XSLT 1.0 solution:
<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>
When this XSLT 1.0 transformation is applied on the same XML document (above), the wanted result (each line of the text node, prepended with the string "line: "
) is produced:
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
Explanation:
Recursive named template to extract and output each next line. Stop condition -- when the string has zero length.
Appropriate use of substring-before()
, substring-after()
and a sentinel technique to minimize code length and complexity.
Upvotes: 4
Reputation: 167571
Well with XSLT 2.0 as supported by Saxon 9 or AltovaXML tools and others you can use the tokenize
function e.g.
<xsl:template match="screen">
<xsl:for-each select="tokenize(., '\n')">
<xsl:value-of select="concat('-', .)"/>
</xsl:for-each>
</xsl:template>
With XSLT 1.0 you could check whether your processor supports an extension function like http://www.exslt.org/str/functions/tokenize/index.html.
Upvotes: 4