如何使用AppleScript从JSON文件获取值?

时间:2018-07-31 15:16:25

标签: json macos applescript

关于这个问题,

How to download and get values from JSON file using VBScript or batch file?

如何从如下所示的JSON文件中获取值

["AA-BB-CC-MAKE-SAME.json","SS-ED-SIXSIX-TENSE.json","FF-EE-EE-EE-WW.json","ZS-WE-AS-FOUR-MINE.json","DD-RF-LATERS-LATER.json","FG-ER-DC-ED-FG.json"]

在MAC OS中使用AppleScript吗?

这是Hackoo在Windows中提供的VBScript代码的一部分,

strJson = http.responseText
Result = Extract(strJson,"(\x22(.*)\x22)")
Arr = Split(Result,",")
For each Item in Arr
    wscript.echo Item
Next
'******************************************
Function Extract(Data,Pattern)
   Dim oRE,oMatches,Match,Line
   set oRE = New RegExp
   oRE.IgnoreCase = True
   oRE.Global = True
   oRE.Pattern = Pattern
   set oMatches = oRE.Execute(Data)
   If not isEmpty(oMatches) then
       For Each Match in oMatches  
           Line = Line & Trim(Match.Value) & vbCrlf
       Next
       Extract = Line
   End if
End Function
'******************************************

在MAC OS AppleScript中,我只需要代码即可将JSON文件的值转换为单个字符串值数组。上面显示的VBScript上方的示例是JSON文件内容的样子。

2 个答案:

答案 0 :(得分:2)

简短的回答::不幸的是,AppleScript没有提供类似于JavaScript的JSON.parse()方法的内置功能来解析JSON。

以下是几种解决方案:

  • 解决方案1 ​​:需要安装第三方插件,但这可能并不总是可行的。
  • 解决方案2 :不需要安装任何第三方插件,而是使用macOS内置的工具/功能作为标准。

解决方案1:

如果可以在用户系统上安装第三方插件,则可以安装JSON Helper for AppleScript (如@ user3439894在评论中所建议)。。 / p>

然后按如下所示在AppleScript中使用它:

set srcJson to read POSIX file (POSIX path of (path to home folder) & "Desktop/foobar.json")
tell application "JSON Helper" to set myList to read JSON from srcJson

说明:

  1. 第1行上,我们读取.json文件的内容,并将其分配给名为srcJson的变量。

    注意。您需要根据需要更改路径部分(即Desktop/foobar.json)。

  2. 第2行中,我们使用 JSON Helper 插件解析内容。这会将源JSON数组的每个项目分配给新的AppleScript list。结果AppleScript list被分配给名为myList的变量。


解决方案2:

通过使用标准内置于macOS的内置工具,您还可以通过AppleScript执行以下操作。假设您的JSON文件为valid,并且仅包含一个Array:

set TID to AppleScript's text item delimiters
set AppleScript's text item delimiters to ","
set myList to text items of (do shell script "tr ''\\\\n\\\\r''  ' ' <~/Desktop/foobar.json | sed 's/^ *\\[ *\"//; s/ *\" *\\] *$//; s/\" *, *\"/,/g;'")
set AppleScript's text item delimiters to TID

注意:您需要根据需要更改路径部分(即~/Desktop/foobar.json)。

此外,如果您的.json文件名包含空格,则需要使用\\对其进行转义。例如~/Desktop/foo\\ bar.json

说明:

  1. 第1行上 AppleScript的当前text item delimiters被分配给名为TID的变量。

  2. 第2行上 AppleScript's text item delimiters设置为逗号-当从源JSON数组提取每个单独的值并将每个值分配给新的AppleScript {{ 1}}。

  3. 第3行上,通过do shell script命令执行 shell脚本,该命令执行以下操作:

    • 通过读取list的部分读取源.json文件的内容。当前,此路径假定文件名为~/Desktop/foobar.json,并且位于foobar.json文件夹(您需要将此路径更改为实际文件所在的位置)

      >
    • Desktop的内容(在文件路径前请注意foobar.json)重定向到tr(即读为<的部分)。此翻译将用空格字符替换源tr ''\\\\n\\\\r'' ' '数组内容中可能存在的所有换行符。这样可以确保.json的内容转换为一行。

      注意:JSON数组可以在每个项目之间包含换行符,并且仍然有效,因此,尽管您的问题中给出的示例JSON出现在一行上-但这不是此解决方案的要求也会处理多行。

    • 然后将一行文本通过管道传递到foobar.json的{​​{3}}进行进一步处理(即读取内容为sed的部分)。

        

      | sed 's/^ *\\[ *\"//; s/ *\" *\\] *$//; s/\" *, *\"/,/g;'命令的语法为 s

      让我们分解每个's/regexp/replacement/flags'命令以进一步了解正在发生的事情:

      • s 删除左方括号s/^ *\\[ *\"//,该方括号可以在零个或多个空格字符之前或之后,并在其后加上双引号(即首次出现)。

      • [ 删除右方括号s/ *\" *\\] *$//,该方括号可以位于零个或多个空格字符之前或之后,并带有双引号(即最后一次出现)。

      • ] 用单个逗号替换单个逗号(可以在前面加上零个或多个空格,和/或后面跟着零个或多个空格)。

      • p>
    • 第3行的开头部分,内容为: s/\" *, *\"/,/g利用set myList to text items of ...将字符串读入AppleScript text items,并使用逗号作为定界符来确定list的各项。结果数组分配给名为list的变量。

  4. 第4行上 myList恢复为其原始值。

为源JSON文件路径使用变量。

如果您想使用变量作为源AppleScript's text item delimiters文件的文件路径,则可以执行以下操作:

.json

注意:这与第一个示例非常相似。显着的区别是:

  • 在第一行,我们将文件路径分配给名为set srcFilePath to quoted form of (POSIX path of (path to home folder) & "Desktop/foobar.json") set TID to AppleScript's text item delimiters set AppleScript's text item delimiters to "," set myList to text items of (do shell script "tr ''\\\\n\\\\r'' ' ' <" & srcFilePath & " | sed 's/^ *\\[ *\"//; s/ *\" *\\] *$//; s/\" *, *\"/,/g;'") set AppleScript's text item delimiters to TID 的变量。
  • srcFilePath中,我们引用了do shell script变量。

有关JSON转义的特殊字符的补充说明: 解决方案2 保留源JSON数组值中可能存在的所有JSON s command。但是,解决方案1 ​​将对其进行解释。

当源JSON数组中的项目包含逗号时,

注意事项 解决方案2 会产生意外结果,因为逗号用作srcFilePath

答案 1 :(得分:1)

  

如何从如下所示的JSON文件中获取值

     

["AA-BB-CC-MAKE-SAME.json","SS-ED-SIXSIX-TENSE.json","FF-EE-EE-EE-WW.json","ZS-WE-AS-FOUR-MINE.json","DD-RF-LATERS-LATER.json","FG-ER-DC-ED-FG.json"]

如果您的意思实际上是您写的内容,并且JSON文件的内容是单个数组中六个字符串的列表,并且以单行格式设置,则最简单的方法是将其视为文本,并剪裁开头和将方括号括起来,然后在每次,出现时划定其字段。最后,每个单独的文本项也可以修剪周围的引号。

检查VBScript似乎使用了非常相似的过程,尽管使用了正则表达式,但AppleScript没有此功能,但是在这种简单情况下并不需要。

让我们假设上面的JSON数组存储在桌面上名为“ myfile.json”的文件中。然后:

    set home to the path to home folder
    set f to the POSIX path of home & "Desktop/myfile.json"

    set JSONstr to read POSIX file f

    # Trim square brackets
    set JSONstr to text 2 thru -2 of JSONstr

    # Delimit text fields using comma
    set the text item delimiters to ","
    set Arr to the text items of JSONstr

    # Trim quotes of each item in Arr
    repeat with a in Arr
        set contents of a to text 2 thru -2 of a
    end repeat

    # The final array
    Arr
  

我只需要代码即可将JSON文件的值转换为单个字符串值数组。上面显示的VBScript上方的示例是JSON文件内容的样子。

变量Arr现在包含字符串值的数组(在AppleScript中称为 lists )。您可以像这样访问其中的特定项目:

    item 2 of Arr --> "SS-ED-SIXSIX-TENSE.json"

更通用的解决方案

我决定在AppleScript中包括一种处理JSON的更高级的方法,部分原因是我最近一直在进行大量JSON处理,而这在我的事件视野中都是新鲜的。而且还证明了使用AppleScriptObjC解析甚至非常复杂的JSON数据不仅是可能的,而且非常简单。

在这种情况下,我认为您不需要它,但是它可能对将来的某些情况很有用。

该脚本包括三个部分:开始导入相关的Objective-C框架,该框架赋予AppleScript其他功能;然后,我定义实际的处理程序本身,称为JSONtoRecord,下面将对其进行描述。最后,进入脚本的底部,您可以在其中输入代码并对其执行任何操作:

    use framework "Foundation"
    use scripting additions
    --------------------------------------------------------------------------------
    property ca : a reference to current application
    property NSData : a reference to ca's NSData
    property NSDictionary : a reference to ca's NSDictionary
    property NSJSONSerialization : a reference to ca's NSJSONSerialization
    property NSString : a reference to ca's NSString
    property NSUTF8StringEncoding : a reference to 4
    --------------------------------------------------------------------------------
    on JSONtoRecord from fp
        local fp

        set JSONdata to NSData's dataWithContentsOfFile:fp

        set [x, E] to (NSJSONSerialization's ¬
            JSONObjectWithData:JSONdata ¬
                options:0 ¬
                |error|:(reference))

        if E ≠ missing value then error E

        tell x to if its isKindOfClass:NSDictionary then ¬
            return it as record

        x as list
    end JSONtoRecord
    --------------------------------------------------------------------------------
    ###YOUR CODE BELOW HERE
    #
    #
    set home to the path to home folder
    set f to the POSIX path of home & "Desktop/myfile.json"

    JSONtoRecord from f

    --> {"AA-BB-CC-MAKE-SAME.json", "SS-ED-SIXSIX-TENSE.json", ¬
    --> "FF-EE-EE-EE-WW.json", "ZS-WE-AS-FOUR-MINE.json", ¬
    --> "DD-RF-LATERS-LATER.json", "FG-ER-DC-ED-FG.json"}

在脚本的底部,我调用了JSONtoRecord处理程序,并向其传递了myfile.json的位置。此处理程序的好处之一是,文件是全行格式化还是多行格式化都无关紧要。它还可以处理复杂的嵌套JSON数组。

在这些情况下,它返回的是本地AppleScript record对象,所有JSON变量均作为属性值存储在记录中。这样,访问变量就变得非常简单。

这实际上就是几个人已经提到的 JSON Helper 应用程序的本质。

一个标准(除了包含有效JSON数据的JSON文件之外)是文件的路径是完整写入的posix路径,例如/Users/CK/Desktop/myfile.json不是 ~/Desktop/myfile.json,或者更糟糕的是,Macintosh HD:Users:CK:Desktop:myfile.json