2012-10-26 69 views
0

我想將蘋果plist文件轉換爲JUnit XML格式,以便Hudson/Jenkins可以讀取結果。Plist到JUnit XML通過XSL

我有一個類似的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> 

,我需要轉換爲XML的JUnit。下面是輸出II期待以上的plist FIEL:

<?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] ='測試A'並將消息插入<failure>的值?我不知道如何執行此操作,因爲錯誤消息包含在另一個<dict>節點中。

編輯:

確定我已經打破這個分解成僞代碼雜交:

  1. 計算所有與整數的節點= 4

  2. 找出每個位置的整數= 4並存儲在變量中的節點

  3. 通過每個節點ħ整數= 4和找到整數= 4

    1. 下一個節點之前的任何字符串[1] =「失敗」如果任何字符串[1] =「失敗」然後查找並串[1] =「錯誤'與整數= 4,並用整數前一節點之後的下一個節點之前= 4

      1. 如果任何字符串[1] =‘錯誤’,與串輸出failure [2]從當前節點和串[2]從前一個節點的整數= 4.
    2. 其他輸出failure帶字符串[2] from previ與整數= 4

節點參照的plist /字典/陣列/字典

的OU節點這是可能的XSL?

+0

而不是說你想要「使用XSL這樣的東西」,最好解釋一下你的源XML應該轉換成你想要的結果的規則。 – ABach

+0

@ABach是更好嗎? – stackErr

+0

那麼,有點 - 但你刪除了你想要的輸出的例子。 :)帶回來,我們應該做生意。 – ABach

回答

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>後代,其<integer>孩子有4
  • 值的第二模板的所有元素<dict>其第一<string>孩子有「失敗」的值相匹配。在這種情況下,會創建一個新的<testcase><failure>元素對,並給出符合您提供的規則的值。
  • 最終模板匹配所有<dict>元素,其第一個<string>子元素的值不是「失敗」。在這種情況下,將創建一個新的<testcase>元素,並根據您的規則給出值。
+0

您的代碼不包含''標籤,但除此之外它完美地工作!我沒有太多的XSL模板的經驗,我沒有任何想法如何工作。你可以解釋嗎? – stackErr

+0

我的歉意 - 我修改了我的答案,添加了''元素。另外,我已經添加了關於這個XSLT如何工作的簡要描述。如果您還有其他問題,請告訴我。 – ABach

+0

非常感謝您解釋您的代碼,因爲我需要添加更多條件才能獲得最終輸出,所以幫助我很多。 – stackErr