I. Решение 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>
Когда это преобразование XSLT 1.0 применяется к тому же XML-документу (см. Выше), будет получен требуемый результат (каждая строка текстового узла с добавлением строки "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()
и сторожевой техники для минимизации длины и сложности кода.