I need help with modifying an ASObjC handler that @ShaneStanley helped me with some time ago, that gets a value for a key in an ASObjC NSDictionary.
The current handler (below) seems to work only if the key is in a top level node.
I need for it to work for all levels of a node, as defined by the XML tag <dict> . . . </dict>
.
All help and suggestions are greatly appreciated.
My objective is this:
- For each Node (in my case a KM Script Action) identified by the value of a XML key “MacroActionType”, get the value of another key, “Path”, in the same node.
- This should be done regardless of what level the target Node is located at.
So, for example, given the XML at the bottom of this post, the Nodes for <MacroActionType>
= “Execute AppleScript”, would be the first and third <dict>
inside of the node:
<key>ThenActions</key>
<array>
The <Path>
values for each of these found Nodes would be:
- [an empty string]
- “%Variable%DND__KM_Scripts_Folder%/Test 2 AppleScript File.scpt”
Example of a Typical Script Action Node (simplified)
<dict>
<key>DisplayKind</key>
<string>Variable</string>
<key>HonourFailureSettings</key>
<true/>
<key>IncludeStdErr</key>
<true/>
<key>MacroActionType</key>
<string>ExecuteJavaScriptForAutomation</string>
<key>NotifyOnFailure</key>
<false/>
<key>Path</key>
<string>%Variable%DND__KM_Scripts_Folder%/Test JXA File.scpt</string>
<key>StopOnFailure</key>
<false/>
<key>Text</key>
<string></string>
<key>Variable</key>
<string>Local__ScriptResults</string>
</dict>
Here are the existing handlers:
Current NSDictionary Handlers
on getDict(pXML) -- @Dict @ASObjC @KMLib
set theString to current application's NSString's stringWithString:pXML
-- convert string to data
set stringData to theString's dataUsingEncoding:(current application's NSUTF8StringEncoding)
-- convert plist to mutable dictionary
set {mutableDict, theError} to current application's NSPropertyListSerialization's propertyListWithData:stringData options:(current application's NSPropertyListMutableContainersAndLeaves) format:(missing value) |error|:(reference)
if mutableDict is missing value then error (theError's localizedDescription() as text)
return mutableDict
end getDict
on getValueForKey(pActionName, poDict, pKeyStr) -- @KMLib
set LF to linefeed
--- extract Object for Key ---
set nsValueForKey to poDict's objectForKey:pKeyStr
--- Convert to nsArray to Get Proper AS Class ---
(*
FROM: Shane Stanley (2016-06-13)
https://lists.apple.com/archives/applescript-users/2016/Jun/msg00080.html
What this does is makes a single-item array containing theResult.
When that's converted to an AppleScript list, the item within it
will also be converted to an AppleScript item if it can.
So this covers all the bridgeable AS classes
-- text, numbers, lists, records, whatever [including missing value]
*)
set nsValueForKeyArray to current application's NSArray's arrayWithArray:{nsValueForKey}
set valueForKey to item 1 of (nsValueForKeyArray as list)
if (valueForKey is missing value) then ## ERROR Msg ##
set valueForKey to ""
set msgStr to "❯❯❯ ERROR ❮❮❮" & LF & ¬
"'" & pKeyStr & "' key was NOT found in XML for Action: " & LF & pActionName
set titleStr to "Handler: getValueForKey"
beep
my dispDialog(msgStr, {"Cancel"})
end if
return valueForKey
end getValueForKey
Example XML to Use with Script
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Actions</key>
<array>
<dict>
<key>Conditions</key>
<dict>
<key>ConditionList</key>
<array/>
<key>ConditionListMatch</key>
<string>All</string>
</dict>
<key>ElseActions</key>
<array/>
<key>MacroActionType</key>
<string>IfThenElse</string>
<key>ThenActions</key>
<array>
<dict>
<key>DisplayKind</key>
<string>Variable</string>
<key>HonourFailureSettings</key>
<true/>
<key>IncludeStdErr</key>
<false/>
<key>MacroActionType</key>
<string>ExecuteAppleScript</string>
<key>Path</key>
<string></string>
<key>Text</key>
<string>-- Script without a PATH --
set x to 1
</string>
<key>UseText</key>
<true/>
<key>Variable</key>
<string>Local__ScriptResults</string>
</dict>
<dict>
<key>DisplayKind</key>
<string>Variable</string>
<key>MacroActionType</key>
<string>ExecuteJavaScriptForAutomation</string>
<key>NotifyOnFailure</key>
<false/>
<key>Path</key>
<string>%Variable%DND__KM_Scripts_Folder%/Test JXA File.scpt</string>
<key>StopOnFailure</key>
<false/>
<key>Variable</key>
<string>Local__ScriptResults</string>
</dict>
<dict>
<key>DisplayKind</key>
<string>Variable</string>
<key>MacroActionType</key>
<string>ExecuteAppleScript</string>
<key>Path</key>
<string>%Variable%DND__KM_Scripts_Folder%/Test 2 AppleScript File.scpt</string>
<key>Text</key>
<string>-- Script without a PATH --
set x to 1
</string>
<key>Variable</key>
<string>Local__ScriptResults</string>
</dict>
</array>
<key>TimeOutAbortsMacro</key>
<true/>
</dict>
</array>
<key>MacroActionType</key>
<string>Group</string>
<key>TimeOutAbortsMacro</key>
<true/>
</dict>
</plist>