【问题标题】:Plist to JUnit XML via XSL通过 XSL Plist 到 JUnit XML
【发布时间】:2012-10-26 17:29:46
【问题描述】:

我正在尝试将 Apple 的 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' 之间的任何错误消息并将消息插入到 &lt;failure&gt; 的值中?我不确定如何执行此操作,因为错误消息包含在另一个 &lt;dict&gt; 节点中。

编辑:

好的,我已将其分解为伪 ish 代码:

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

  2. 找出每个整数=4的节点的位置,并存入一个变量

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

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

      1. 如果任何 string[1] = 'Error',则输出 failure,字符串 [2] 来自当前节点,字符串 [2] 来自前一个节点,整数 = 4。
    2. Else 输出 failure,字符串 [2] 来自前一个节点,整数 = 4。

节点引用plist/dict/array/dict

XSL 可以做到这一点吗?

【问题讨论】:

  • 与其说您想要“使用 XSL 的类似的东西”,不如解释一下将源 XML 转换为所需结果的规则。
  • 好吧,有点-但是您删除了所需输出的示例。 :) 把它带回来,我们应该做生意了。
  • @ABach 为我提供的 plist 文件添加了我想要的输出

标签: xml xslt plist


【解决方案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>

说明:

  • 第一个模板创建新的&lt;testsuites&gt;&lt;testsuite&gt; 元素。然后指示 XSLT 处理器处理所有 &lt;dict&gt; 子代的 &lt;integer&gt; 子代的值为 4。
  • 第二个模板匹配第一个&lt;string&gt; 子元素值为“Fail”的所有&lt;dict&gt; 元素。在这种情况下,将创建一个新的 &lt;testcase&gt;&lt;failure&gt; 元素对,并为其赋予一个符合您提供的规则的值。
  • 最终模板匹配所有&lt;dict&gt; 元素,其第一个&lt;string&gt; 子元素的值不是“Fail”。在这种情况下,将创建一个新的 &lt;testcase&gt; 元素并根据您的规则为其赋予值。

【讨论】:

  • 您的代码不包含&lt;testcase&gt; 标签,但除此之外它运行良好!我对 xsl 模板没有太多经验,也不知道它是如何工作的。你能解释一下吗?
  • 抱歉 - 我修改了答案以添加 &lt;testcase&gt; 元素。此外,我还添加了有关此 XSLT 工作原理的简要说明。如果您还有其他问题,请告诉我。
  • 非常感谢您解释您的代码,对我帮助很大,因为我需要添加更多条件才能获得最终输出。
  • 没问题 - 很乐意提供帮助。 :)
猜你喜欢
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 2016-03-13
  • 2015-06-05
  • 1970-01-01
  • 1970-01-01
  • 2015-03-27
  • 1970-01-01
相关资源
最近更新 更多