Function to easily read values from a plist file

Ken Ray kray at sonsothunder.com
Thu Oct 6 01:40:45 EDT 2005


After Jacque discovered the data in the "preferences.plist" file she needed,
I decided to write a general-purpose function that would get values from a
plist file... it's a bit long, but it takes into account a number of
different scenarios for retrieving data.

Enjoy! And let me know if I need to add/change anything...

Ken
----------
stsReadFromPlist <pathTopListFile>,<keyPath>

This function lets you read from an OS X pList file (unencoded - Tiger has
some pLists encoded) using a slash-delimited "path" of keys in the file. If
the value of the data is a simple <string>, <integer>, etc., the value is
returned. If the value is an array (shown by "<array>" directly under the
key in the plist), an array is returned.

Example 1:
     put "/Library/Preferences/SystemConfiguration/com.apple.nat.plist" \
        into pList
     put stsReadFromPlist(pList,"NAT/Airport/NetworkName")
          --> "PowerMacG4"
     put stsReadFromPlist(pList,"NAT/SharingDevices") into tDevicesA
          --> tDevicesA[1] = "en1"

Example 2:
     put "/Library/Preferences/loginwindow.plist" \
        into pList
     put stsReadFromPlist(pList,"AutoLaunchedApplicationDirectory/Hide")
          --> "false"


function stsReadFromPlist pFile,pKeyPath
  if there is a file pFile then
    put url ("file:" & pFile) into tData
    set the itemDel to "/"
    repeat for each item tItem in pKeyPath
      put offset("<key>" & tItem & "</key>",tData) into tOffset
      if tOffset <> 0 then
        delete char 1 to (tOffset+length("<key>"&tItem&"</key>")) of tData
      else
        return "STSError: Key not found at path '" & pKeyPath & "'"
      end if
    end repeat
    -- remove preceding chars
    repeat
      if char 1 of tData = "<" then exit repeat
      delete char 1 of tData
    end repeat
    if char 1 to 7 of tData ="<array>" then
      -- return an array
      if matchText(tData,"(?si)<array>(.*?)<\/array>",tElements) then
        put "" into tRetValA
        put 0 into tKeyNum
        repeat
          add 1 to tKeyNum
          get matchText(tElements,"(?si)<.*?>(.*?)<\/.*?>",tVal)
          if it is false then exit repeat
          else
            put tVal into tRetValA[tKeyNum]
            get matchChunk(tElements,"(?si)(<.*?>(.*?)<\/.*?>)",tStart,tEnd)
            delete char 1 to tEnd of tElements
          end if
        end repeat
        return tRetValA
      else
        return "STSError: Could not extract array from key path '" & \
           pKeyPath & "'"
      end if
    else
      -- look for <Val/> (like <false/> - this is used in loginwindow.plist)
      if matchText(tData,"(?si)<(.*?)\/>",tVal) then
        return tVal
      else
        -- look for <string>Val</string>, <integer>Val</integer>, etc.
        if matchText(tData,"(?si)<.*?>(.*?)<\/.*?>",tVal) then
          return tVal
        end if
      end if
      return "STSError: Could not extract value from key path '" & \
         pKeyPath & "'"
    end if
  else
    return "STSError: File not found."
  end if
end stsReadFromPlist




More information about the use-livecode mailing list