我正在尝试将Apples plist文件转换为JUnit XML格式,因此Hudson / Jenkins可以读取结果。
我有一个与此类似的plist文件输出:
<plist><dict><array>
<dict>
<key>LogType</key>
<string>Pass</string>
<key>Message</key>
<string>Test 1</string>
<key>Timestamp</key>
<date>2012-10-26T09:42:41Z</date>
<key>Type</key>
<integer>4</integer>
</dict>
<dict>.....</dict>
.
.
.
<dict>
<key>LogType</key>
<string>Pass</string>
<key>Message</key>
<string>Test 1</string>
<key>Timestamp</key>
<date>2012-10-26T09:43:27Z</date>
<key>Type</key>
<integer>5</integer>
</dict>
<dict>
<key>LogType</key>
<string>Fail</string>
<key>Message</key>
<string>Inserting content to a group</string>
<key>Timestamp</key>
<date>2012-10-26T09:49:13Z</date>
<key>Type</key>
<integer>4</integer>
</dict>
<dict>.....</dict>
.
.
.
<dict>
<key>LogType</key>
<string>Error</string>
<key>Message</key>
<string>VerboseError: target.frontMostApp().mainWindow().buttons()[3] could not be tapped</string>
<key>Screenshot</key>
<string></string>
<key>Timestamp</key>
<date>2012-10-26T09:50:12Z</date>
<key>Type</key>
<integer>3</integer>
</dict>
<dict>
<key>LogType</key>
<string>Fail</string>
<key>Message</key>
<string>Inserting content to a group</string>
<key>Screenshot</key>
<string></string>
<key>Timestamp</key>
<date>2012-10-26T09:50:13Z</date>
<key>Type</key>
<integer>7</integer>
</dict>
</array></dict>
</plist>
我需要转换为JUnit XML。以下是上述plist场所预期的输出:
<?xml version="1.0"?>
<testsuites>
<testsuite>
<testcase classname="Test 1" name="Test 1"/>
<testcase classname="Inserting content to a group" name="Inserting content to a group">
<failure>Inserting content to a group - VerboseError: target.frontMostApp().mainWindow().buttons()[3] could not be tapped< </failure>
</testcase>
</testsuite>
</testsuites>
目前我有这个XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<testsuites>
<testsuite>
<xsl:for-each select="plist/dict/array/dict">
<xsl:if test="integer = 4">
<testcase>
<xsl:attribute name="classname"><xsl:value-of select="string[2]" /></xsl:attribute>
<xsl:attribute name="name"><xsl:value-of select="string[2]"/></xsl:attribute>
<xsl:if test="string[1] = 'Fail'">
<failure>
<xsl:attribute name="type"><xsl:value-of select="integer" /></xsl:attribute><xsl:value-of select="string[2]" />
</failure>
</xsl:if>
</testcase>
</xsl:if>
</xsl:for-each>
</testsuite>
</testsuites>
</xsl:template>
</xsl:stylesheet>
如何编辑上面的XSL以查找两个dict / string [2] ='Test A'之间的任何错误消息,并将消息插入<failure>
的值?我不知道如何执行此操作,因为错误消息包含在另一个<dict>
节点中。
修改
好的我已将其分解为伪ish代码:
使用integer = 4计算所有节点。
找出每个具有整数= 4的节点的位置并存储在变量中
使用integer = 4遍历每个节点,并在整数= 4的下一个节点之前找到任何字符串[1] ='Fail'。
如果任何字符串[1] ='失败',则在具有整数= 4的下一个节点之前以及在整数= 4之前的节点之后找到并且字符串[1] ='错误'。
failure
,并使用整数= 4从前一节点输出字符串[2]。failure
,其字符串[2]来自上一节点,整数= 4。节点引用plist / dict / array / dict
这可以用XSL吗?
答案 0 :(得分:1)
你的规则有点令人困惑,但我相信我有一个解决方案。
当这个XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output omit-xml-declaration="no" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/*">
<testsuites>
<testsuite>
<xsl:apply-templates select="/*/*/*/dict[integer = '4']" />
</testsuite>
</testsuites>
</xsl:template>
<xsl:template match="dict[string[1] = 'Fail']">
<testcase classname="{string[2]}" name="{string[2]}">
<failure>
<xsl:value-of select="string[2]" />
<xsl:if test="following-sibling::dict[1]/string[1] = 'Error'">
<xsl:value-of select="concat( ' - ', following-sibling::dict[string[1] = 'Error'][1]/string[2])" />
</xsl:if>
</failure>
</testcase>
</xsl:template>
<xsl:template match="dict[not(string[1] = 'Fail')]">
<testcase classname="{string[2]}" name="{string[2]}" />
</xsl:template>
</xsl:stylesheet>
..适用于提供的XML:
<?xml version="1.0" encoding="utf-8"?>
<plist>
<dict>
<array>
<dict>
<key>LogType</key>
<string>Pass</string>
<key>Message</key>
<string>Test 1</string>
<key>Timestamp</key>
<date>2012-10-26T09:42:41Z</date>
<key>Type</key>
<integer>4</integer>
</dict>
<dict>
<key>LogType</key>
<string>Pass</string>
<key>Message</key>
<string>Test 1</string>
<key>Timestamp</key>
<date>2012-10-26T09:43:27Z</date>
<key>Type</key>
<integer>5</integer>
</dict>
<dict>
<key>LogType</key>
<string>Fail</string>
<key>Message</key>
<string>Inserting content to a group</string>
<key>Timestamp</key>
<date>2012-10-26T09:49:13Z</date>
<key>Type</key>
<integer>4</integer>
</dict>
<dict>
<key>LogType</key>
<string>Error</string>
<key>Message</key>
<string>VerboseError:
target.frontMostApp().mainWindow().buttons()[3] could not
be tapped</string>
<key>Screenshot</key>
<string />
<key>Timestamp</key>
<date>2012-10-26T09:50:12Z</date>
<key>Type</key>
<integer>3</integer>
</dict>
<dict>
<key>LogType</key>
<string>Fail</string>
<key>Message</key>
<string>Inserting content to a group</string>
<key>Screenshot</key>
<string />
<key>Timestamp</key>
<date>2012-10-26T09:50:13Z</date>
<key>Type</key>
<integer>7</integer>
</dict>
</array>
</dict>
</plist>
...产生预期结果:
<?xml version="1.0"?>
<testsuites>
<testsuite>
<testcase classname="Test 1" name="Test 1" />
<testcase classname="Inserting content to a group"
name="Inserting content to a group">
<failure>Inserting content to a group - VerboseError:
target.frontMostApp().mainWindow().buttons()[3] could not be
tapped</failure>
</testcase>
</testsuite>
</testsuites>
<强>解释强>
<testsuites>
和<testsuite>
元素。然后指示XSLT处理器处理<dict>
子项值为4的所有<integer>
个后代。<dict>
子元素值为“Fail”的所有<string>
个元素。在这种情况下,会创建一个新的<testcase>
和<failure>
元素对,并为其提供符合您提供的规则的值。<dict>
个元素,其第一个<string>
子元素的值除“失败”以外的任何值。在这种情况下,会创建一个新的<testcase>
元素,并根据您的规则给出值。