2013-07-15 37 views
3

我正在iOS設備和企業應用程序的模擬器上進行一些更高級的自動化操作。自動化是用無瀏覽器的Javascript編寫的。其中一種方法適用於設備,但不適用於模擬器,所以我需要編寫一個解決方法。好奇的是,它是UIATarget.localTarget()。frontMostApp()。preferencesValueForKey(key)。用JavaScript和正則表達式從文件中獲取XML標籤的最有效方法

我們需要做的是從磁盤上的plist文件中讀取一個服務器的路徑(其變化)。由於在模擬器一種變通方法,我用下面的行定位包含喜好plist文件:

// Get the alias of the user who's logged in 
var result = UIATarget.localTarget().host().performTaskWithPathArgumentsTimeout("/usr/bin/whoami", [], 5).stdout; 

// Remove the extra newline at the end of the alias we got 
result = result.replace('\n',""); 

// Find the location of the plist containing the server info 
result = UIATarget.localTarget().host().performTaskWithPathArgumentsTimeout("/usr/bin/find", ["/Users/"+result+"/Library/Application Support/iPhone Simulator", "-name", "redacted.plist"], 100); 

// For some reason we need a delay here 
UIATarget.localTarget().delay(.5); 

// Results are returned in a single string separated by newline characters, so we can split it into an array 
// This array contains all of the folders which have the plist file under the Simulator directory 
var plistLocations = result.stdout.split("\n"); 

... 

// For this example, let's just assume we want slot 0 here to save time 
var plistBinaryLocation = plistLocations[0]; 
var plistXMLLocation = plistLocations[i] + ".xml"; 
result = UIATarget.localTarget().host().performTaskWithPathArgumentsTimeout("/usr/bin/plutil", ["-convert","xml1", plistBinaryLocation,"-o", plistXMLLocation], 100); 

從這裏,我想獲得的內容最好的辦法是貓或者用grep的文件,因爲我們無法直接從磁盤讀取文件。但是,我無法解決語法問題。這裏的plist文件我讀的編輯片段:

<key>server_url</key> 
<string>http://pathToServer</string> 

還有一堆的文件,其中的關鍵SERVER_URL是獨一無二的鍵/字符串對。理想情況下,我會做一些回顧,但由於JavaScript似乎不支持它,所以我想我只是從文件中獲得一對,稍後再減少它。

我可以搜索與此鍵:

// This line works 
var expression = new RegExp(escapeRegExp("<key>server_url</key>")); 

if(result.stdout.match(expression)) 
{ 
    UIALogger.logMessage("FOUND IT!!!"); 
} 
else 
{ 
    UIALogger.logMessage("NOPE :("); 
} 

凡escapeRegExp方法是這樣的:

function escapeRegExp(str) 
{ 
    var result = str.replace(/([()[{*+.$^\\|?])/g, '\\$1'); 

    UIALogger.logMessage("NEW STRING: " + result); 
    return result; 
} 

另外,該線路返回一個值(但得到了錯誤的路線):

var expression = new RegExp(escapeRegExp("<string>(.*?)</string>")); 

然而,當你把它們放在一起時,它(正則表達式語法)在終端上工作,但沒有工作在代碼:

var expression = new RegExp(escapeRegExp("<key>server_url</key>[\s]*<string>(.*?)</string>")); 

我錯過了什麼?我也試過grep和egrep,沒有任何運氣。

回答

1

有兩個問題影響你在這裏得到正則表達式在你的JavaScript代碼中工作。

  • 首先,你逃避了整個正則表達式字符串,這意味着你的拍攝(.*?)和你的空格忽略[\s]*也將逃脫,也不會評價你期待的方式。您需要轉義XML部分並添加正則表達式部分而不會轉義它們。
  • 其次,空白忽略部分[\s]*正在成爲JavaScript正常字符串轉義規則的犧牲品。 「\ s」在輸出中變成「s」。您需要使用「\ s」將該反斜槓轉義,以便在傳遞給構造正則表達式的字符串中保留「\ s」。

我已經構建了一個工作腳本,我已經在UI自動化引擎自身中進行了驗證。它應該提取並打印出預期網址:

var testString = "" + 
"<plistExample>\n" + 
" <key>dont-find-me</key>\n" + 
" <string>bad value</string>\n" + 
" <key>server_url</key>\n" + 
" <string>http://server_url</string>\n" + 
"</plistExample>"; 

function escapeRegExp(str) 
{ 
    var result = str.replace(/([()[{*+.$^\\|?])/g, '\\$1'); 

    UIALogger.logMessage("NEW STRING: " + result); 
    return result; 
} 

var strExp = escapeRegExp("<key>server_url</key>") + "[\\s]*" + escapeRegExp("<string>") + "(.*)" + escapeRegExp("</string>"); 

UIALogger.logMessage("Expression escaping only the xml parts:" + strExp); 

var exp = new RegExp(strExp); 
var match = testString.match(exp); 

UIALogger.logMessage("Match: " + match[1]); 

我應該指出,雖然,你需要在正則表達式逃脫的唯一事情是正斜槓在XML關閉標籤。這意味着你不需要你的escapeRegExp()函數,並且可以寫出如下所示的表達式:

var exp = new RegExp("<key>server_url<\/key>[\\s]*<string>(.*)<\/string>"); 
+0

這很好用!感謝您成爲UIAutomation社區的積極成員。你的電子書是那裏唯一的高級iOS自動化書籍之一,所以我真的很感激它:)。 –

+1

謝謝,我很榮幸。 :)既然你打破了冰面,提到了這本書,我希望這對我未來的訪客來說是一個不錯的形式:http://pragprog.com/book/jptios –

相關問題