0

AppleのplistファイルをJUnitXML形式に変換して、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>

これをJUnitXMLに変換する必要があります。上記の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を編集して、2つのdict / string [2] ='Test A'の間にエラーメッセージを見つけ、そのメッセージをの値に挿入するにはどうすればよい<failure>ですか?<dict>エラーメッセージが別のノードに含まれているため、これを行う方法がわかりません。

編集:

わかりました。これを疑似ishコードに分解しました。

  1. 整数=4のすべてのノードをカウントします。

  2. 整数=4の各ノードの位置を見つけて、変数に格納します

  3. integer = 4の各ノードを調べて、integer=4の次のノードの前にstring[1]='Fail'を見つけます。

    1. いずれかのstring[1]='Fail'の場合、string [1] ='Error'を見つけて、整数= 4の次のノードの前、および整数=4の前のノードの後に​​見つけます。

      1. string [1] ='Error'の場合、failure現在のノードからstring [2]を、整数=4の前のノードからstring[2]を出力します。
    2. failureそれ以外の場合は、整数=4の前のノードからstring[2]を使用して出力します。

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>and<testsuite>要素を作成します。XSLT プロセッサは、子の値が 4 であるすべての<dict>子孫を処理するように指示されます。<integer>
  • 2 番目のテンプレートは、最初の子の値が "Fail" であるすべての<dict>要素に一致します。<string>この場合、新しい要素<testcase><failure>ペアが作成され、指定したルールに準拠する値が与えられます。
  • 最終的なテンプレートは、最初の子の値が「Fail」以外のすべての<dict>要素と一致します。<string>この場合、新しい<testcase>要素が作成され、ルールに従って値が指定されます。
于 2012-10-26T23:56:21.877 に答える