How to read property list (plist) items ?

System Events’s Property List Suite is good if you know (and can rely on!) the structure of the property lists. Assuming that by “ShortURL” key you mean “SoftURL” key, the strings can be extracted from plists like the one in your original post like this:

set filePath to ((path to desktop as text) & "Test.plist") -- Or wherever your file is. Must be a path.

tell application "System Events"
	set SoftURLs to value of property list item "SoftURL" of ¬
		property list item "NetRestore" of ¬
		every property list item of ¬
		property list item "ProductTest" of ¬
		property list item "FiletoDownloadVersions" of ¬
		property list item "2" of ¬
		property list item "FiletoDownload" of ¬
		contents of property list file filePath
end tell
--> {"http://website.com/test1.soft.zip", "http://website.com/test2.soft.zip"}

I find that sometimes it’s just easier to work with the plist in applescript. Then you can use all of your applescript skills to find the information rather than using property list syntax. For example you can convert your example plist into an applescript object like this and then work with it however you need.

set f to (path to desktop as text) & "test.plist"

tell application "System Events"
	set theContents to contents of property list file f
	set theValue to value of theContents
end tell

return {class of theValue, theValue}

Now that you can see it, it’s not too hard to create this to get your answer…

set f to (path to desktop as text) & "test.plist"
tell application "System Events"
	set theContents to contents of property list file f
	set theValue to value of theContents
end tell

set softURL1 to SoftURL of NetRestore of |1a001| of ProductTest of FiletoDownloadVersions of |2| of FiletoDownload of theValue
set softURL2 to SoftURL of NetRestore of |1b001| of ProductTest of FiletoDownloadVersions of |2| of FiletoDownload of theValue
return {softURL1, softURL2}
--{"http://website.com/test1.soft.zip", "http://website.com/test2.soft.zip"}

The point for me is to see the plist information in applescript so I have an understanding of the structure. As Nigel mentions, you have to know about the structure if you want to do something with it via applescript property list file syntax.

The problem, though, is that you have parsed the sample – I suspect the full XML includes a lot more than |1a001| and |1b001|. That’s why I think something based on an XPath query would be more the go.

Advantage of property list items is that the file will be serialized as well while XML only parses the file, the other advantage is that I (personally) prefer to use as less 3rd party software as possible. So if the list gets bigger you can simply use something like:

set f to (path to desktop as text) & "test.plist"
tell application "System Events"
	tell (value of (contents of property list file f)) as record
		set softURLs to {}
		repeat with p in productTest of FiletoDownloadVersions of |2| of FiletoDownload of it as list
			set end of softURLs to softURL of NetRestore of p
		end repeat
	end tell
end tell

return softURLs

Yes. “Vanilla rules!” That was more or less the point of my earlier post.

  • use the plist as such, it’s a native format
  • use the software provided to read it: System Events
  • use the native data type it returns: record

(I tend to simplify to the bare bone) :stuck_out_tongue:

Hello!

My few cents is that System Events is single threaded, and a major component for scripters, and should be avoid being bogged down at all costs, as it can lead to unstability, at least slow repsonses. Because what happens when the propertylist file is malformed for example?

So, when it comes to parsing of propertylist files, I’d prefer xmllib of Satimage, or XPath queries.

That’s just me.

Because what happens when the propertylist file is malformed for example?

A timeout will occur, restart the application or you will receive an error and nothing is wrong.

The problem you describe applies for scripting additions not for applications. Even knowing that OSAX allows (since 10.6) thread safe handlers doesn’t mean they are. They all respond to events in the main queue, so if one event hangs in XMLLib the rest will so as well.

For example you can’t pipe data from one script to another using shell script, because do shell script in script 1 is waiting for data, script 2 can’t even start because an event in script 1 is blocking your script. You can only make it useful when you completely run two different applications (file must be saved as application).

Hello!

Then it seems to me like XPath is the way to go, when parsing large propertylist files.

Are you saying, that if any OSAX hangs for some reason, then all other applevents in that queue will be put on hold, until that hang, is resolved? -I don’t know how it is resolved, but I guess it is removed when a timeout occurs, am I right?

Because this is interesting :slight_smile: I always thought the the eventqueue flowed freely, but that if something kept System Events from responding, then only those events waiting for System Events would have to wait.

With your explanation, I now think that if something goes awry towards a a scripting addition, on the eventqueue, then the whole eventqueue is put on hold.

Is that right? (And I haven’t come around to reading the System Overview yet.)

a simple test:

Terminal (multi threading):
create a named pipe (mkfifo)
try to print the file (it seems like nothing happens)
open a second window and echo some data to the named pipe
The result is that you see the echoed data in window 2 will be printed in the first window.

AppleScript (single threaded)
using the same pipe
try to get data from the named pipe (do shell script “cat …”)
open a second window in script editor
Now send some data to the named pipe (do shell script “echo blahblah > …”)
The result is that the event in the second window waits till the first event is ready and can continue.

This seems weird but isn’t. Both scripts have the same current application, which means have the same event queue even if it runs in a different thread. Osax events are (must) send to the current application which means that your own application starts to hang. I think you’re better off when an external application is hanging that your own; you have no control.

Ok!
So if I have several scripts running, (hypothetically) and they all use say AppleScript Runner, then they will be processed in a single thread.

But if I use different script runners, then they may process in parallell. But System Events, is an application, so there is the next bottleneck, as it doesn’t spawn a process for each thread, but handles all in one fifo queue.

Have I got it right?

Correct! You can run another instance of the application but AS doesn’t support it.

It’s not quite that simple. For example, ASObjC Runner receives commands on the main thread, but passes them for processing to a background thread. So if a script sends a command to Runner, another script can send a second command while the first one is being processed.

Hello!

Does that hold for just ASObjC Runner or is it applicable to other Script Runners as well? like AppleScript Runner, and osascript.

And I guess that holds for ASObjC Runner and maybe the others, as long as there isn’t any shared resource involved, System Events would be such a resource, that they would have to line up and wait for, as System Events is single threaded.

Or the threads ends up in System Events fifo queue should System Events detect a resource conflict?

I guess it holds that System Events is single threaded. That would be in accordance with murphy’s laws.

ASObjC Runner isn’t a script runner in that sense – it’s an app, more like System Events.

Not necessarily. But a lot of stuff SE does, like file-related stuff, is time-consuming, and no amount of coding can make up for that.

Hi,

so far interesting discussion. :slight_smile: Some parts are more advanced, hehehe but I understand most of it. Yes my example is shorter. I have maybe 30 products for “SoftURL” and it will still grow. For sure multithread will be needed maybe in the future. I did not got the time to use all the tricks and codes you gave me but it seems everything I need so far. If you have more to share to speed up the thing with “vanilla code”, I’m open. :wink:

Thank you everybody !

Who says that SE is single threaded, like I said and proved with my OSAX example (do shell script is no part of SE, but part of an OSAX) that your cons about SE applies for OSAX. OSAX allows since 10.6 multi threading (thread safe) but almost everything you find in an OSAX is not thread-safe because it can’t be threaded, like do shell script. Then my second point was that when an external application as SE hangs, you can restart it with your script and try again or give the end-user a warning. When something goes wrong in an OSAX you have to restart the current application which is your script running as application or script editor.

There are however some pros for using OSAX, they are indeed faster (the parenting chain of events is shorter;when you use it right). Also you can embed by creating a folder named ‘Scripting Additions’ inside the resources of your application; this way the end user doesn’t have to worry about the right version of the osax or if the osax is installed or not. OSAX is binded to the current application, no separate process needed. Because a new instance of OSAX is binded to every current application, different (standalone) scripts don’t interfere with each other. So in short the most advantages of an OSAX only applies when you save your script as an application and not running it by an script editor/runner.

Hello!

it was actually you who said it in post #4 in the article AppleScript/Applescript-Studio: Background Code by B. Boertien
That can be found Here

That is my “con” against System Events,being used a as a parser of property list files, espcecially at endusers machines, as it is such a central part, when it comes to scripting, that it is a good idea to not use it as a “work horse” for such purposes, as it may hang, and leave the user in peril.

And it isn’t so, that it is just for some user to restart System Events, there are a lot of users out there, having no idea of what System Events is.

I am even sure, that there are people here, that doesn’t have such a little snippet in their script menu:

#/bin/bash ps -Al | grep System\ Events | head -n 1 | grep grep || killall System\ Events
I do agree fully with you on the purposefullness of Osax’s.

Edit:
And if memory serves me right, I believe you have to drop the space in the the name Application Support within the resources folder, but spell it like ApplicationSupport, in one single word, for it to work properly

That’s certainly true, all else being equal. But there have been plenty of cases, including in commands in Standard Additions, where what is presumably the slowness of the code makes this point rather academic. I haven’t looked recently, but the round command used to be a good example of this.

How ironic :D. No, what I said there was true in that context. I wasn’t talking about System Events in general only some part inside SE. The part I was talking about applies for every application in Mac OS X and every OSAX.

I’m not sure if I understand the ‘hanging’ part to be a reason not to use SE and ever will be or if it applies for me. You have to be realistic, when does SE hangs? I’m using SE for 10 years now without any problems (including hundreds of workstations). Also SE can read compiled/binary and xml plist files because a plist doesn’t need to be XML formatted (said because this topic becomes more general).

Hello!

Lets qualify this a litte more I’am talking about parsing plist files, where you want to exctract more than a couple of keys, maybe 50-100 or so, maybe more.

Then I want to rely on another tool. I use for instance the script menu, and it really bothers me, if that piece stops working because of some action in the system elsewhere, either because it has crashed, or because it is busy.

I am not talking about the plist file of an applett, with 5 entries more of something like the Safari’s plist.file but not that big either, if you get my drift. and if then is any errors in that piece, then things will become unstable.

I am pretty damn sure errors into something like that, with nested structures will keep System Events occupied for a while.

And I am not talking about what happens on my own machine, because I live well with it, I know how to restart System Events. I am talking about distributing such a solution to end users really, and the OP in this post, well he did show as a plist file with errors in.

Under such circumstances, I’d rather use another tool, like XPath, or an external Osax, like Xmllib than System Events for the sake of overall stability.

And that is just me, and it is no big deal really, but that is how I judge matters. Even if System Events was 10 times faster, I’d go for something that keeps the System Events sane, and available, to all of those scripts that are relying on it to work.

I am also very much into using what is already there, but this is one of the exceptions to the rule.