繁体   English   中英

使用JavaScript和Regex从文件中获取XML标记的最有效方法

[英]Most efficient way to grab XML tag from file with JavaScript and Regex

我正在iOS设备和模拟器上为企业应用程序做一些更先进的自动化。 自动化是用无浏览器的Javascript编写的。 其中一种方法适用于设备但不适用于模拟器,因此我需要编写一种解决方法。 对于好奇的,它是UIATarget.localTarget()。frontMostApp()。preferencesValueForKey(key)。

我们需要做的是从磁盘上的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);

从这里开始,我认为获取内容的最佳方法是cat或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而没有任何运气。

在这里,有两个问题会影响您使用正则表达式在JavaScript代码中工作。

  • 首先,您正在转义整个正则表达式表达式字符串,这意味着您的捕获(.*?)和忽略[\\s]*空白也将被转义,并且不会按照您期望的方式进行评估。 您需要转义XML部分并添加正则表达式部分而不转义它们。
  • 其次,空白忽略了部分, [\\s]*正在成为JavaScript正常的字符串转义规则的牺牲品。 “\\ s”在输出中变为“s”。 您需要使用“\\ s”转义反斜杠,以便它在您传递以构造正则表达式的字符串中保持为“\\ s”。

我已经构建了一个我在UI Automation引擎中验证过的工作脚本。 它应该提取并打印出预期的URL:

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>");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM