В следующем XSLT показано, как разделить содержимое log
в токенах, используя tokenize()
. Возможно, есть лучший выбор с XSLT 2.0 (например, xsl:analyze-string
), но из-за использования только tokenize()
это решение применимо также к XSLT 1.0 , расширенному с EXSLT шаблоны.
XSLT 2.0 протестировано на Saxon-B 9.0.0.2J
<xsl:stylesheet version="2.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="/">
<xml>
<xsl:variable name="string" select="."/>
<xsl:variable name="pass" select="tokenize($string,'Passed -ID:')[not(position()=1)]"/>
<xsl:for-each select="$pass">
<xsl:choose>
<xsl:when test="contains(.,'Failed -ID:')">
<xsl:variable name="failure" select="tokenize(.,'Failed -ID:')"/>
<xsl:for-each select="$failure">
<xsl:choose>
<xsl:when test="position()=1">
<testcase name="{tokenize(.,'\s-Log:')[1]}"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="tc" select="tokenize(.,'\s-Log:')"/>
<testcase name="{$tc[1]}">
<failure message="{$tc[2]}"/>
</testcase>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<testcase name="{tokenize(.,'\s-Log:')[1]}"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:apply-templates/>
</xml>
</xsl:template>
<xsl:template match="log"/>
</xsl:stylesheet>
Вышеуказанный XSLT применяется к следующему входу:
<log>Passed -ID:1 -Log:
Passed -ID:2 -Log:Suite
File/Folder
Failed -ID:3 -Log:Suite
Validate Install Failed
Passed -ID:4 -Log:
Failed -ID:5 -Log:aaaaaa
Failed -ID:6 -Log:dfsfsdf
Failed -ID:7 -Log:dsfsfs
fsdfsdfsdfsdfs
Passed -ID:8 -Log:dfsdfsf
Failed -ID:9 -Log:dfsdfs
</log>
Создает следующий вывод:
<xml>
<testcase name="1"/>
<testcase name="2"/>
<testcase name="3">
<failure message="Suite
Validate Install Failed
"/>
</testcase>
<testcase name="4"/>
<testcase name="5">
<failure message="aaaaaa
"/>
</testcase>
<testcase name="6">
<failure message="dfsfsdf
"/>
</testcase>
<testcase name="7">
<failure message="dsfsfs
fsdfsdfsdfsdfs
"/>
</testcase>
<testcase name="8"/>
<testcase name="9">
<failure message="dfsdfs
"/>
</testcase>
</xml>
Обратите внимание, что 

происходит из-за перевода строки исходного текста, потому что мы помещаем содержимое в значение атрибута. Чтобы избавиться от этого, было бы лучше включить сообщение в качестве содержимого элемента failure
. В любом случае следующая статья имеет дело с хитрыми пробелами.