0

我正在尝试将 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 代码:

  1. 计算整数 = 4 的所有节点。

  2. 找出整数 = 4 的每个节点的位置并存储在变量中

  3. 遍历整数 = 4 的每个节点,并在整数 = 4 的下一个节点之前找到任何字符串 [1] = 'Fail'。

    1. 如果有任何字符串 [1] = 'Fail',则在整数 = 4 的下一个节点之前和整数 = 4 的上一个节点之后找到字符串 [1] = 'Error'。

      1. 如果任何 string[1] = 'Error',failure则从当前节点输出 string[2],从前一个节点输出 string[2],整数 = 4。
    2. failure其他带有 string[2] 的输出,来自前一个节点,整数 = 4。

节点引用 plist/dict/array/dict

这对 XSL 可行吗?

4

1 回答 1

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 处理器处理其子节点值为 4 的所有<dict>后代。<integer>
  • 第二个模板匹配<dict>第一<string>个子元素值为“Fail”的所有元素。在这种情况下,将创建一个新的<testcase><failure>元素对,并赋予一个符合您提供的规则的值。
  • 最终模板匹配<dict>其第一<string>个子元素的值不是“Fail”的所有元素。在这种情况下,将创建一个新<testcase>元素并根据您的规则给定值。
于 2012-10-26T23:56:21.877 回答