This is accurate and reasonably fast, but I’m not sure if it’s kosher:
set XMLfile to (choose file) as Unicode text
tell application "System Events" to set XMLrecords to XML elements of XML element 1 of XML file XMLfile
set dbRecords to {}
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to tab as Unicode text
repeat with thisXMLrecord in XMLrecords
-- Read the ID, field names, and field values for this "Package" field.
tell application "System Events" to set {packageID, {labels, vals}} to {value of XML attribute "ID", {name, value} of XML elements} of thisXMLrecord
-- Collate the field names and respective values into a single list.
set labelValuePairs to {}
repeat with i from 1 to (count labels)
set end of labelValuePairs to item i of labels
set end of labelValuePairs to item i of vals
end repeat
-- Use nefarious means to turn this list into an AppleScript record.
set rec to «class seld» of (record {«class usrf»:labelValuePairs} as record)
-- Join the package ID and the ordered values from the AS record into
-- a tab delimited line and add it to the DB record list.
set end of dbRecords to {packageID, get rec's {|Status|, |PIC|, |FinalPostage|, |Balance|, |TransactionID|, |TransactionDateTime|, |PostmarkDate|, |ReferenceID|, |Description|, |WeightOz|}} as Unicode text
end repeat
-- Join the lines into a single text using returns.
set AppleScript's text item delimiters to return as Unicode text
set dbText to dbRecords as Unicode text
set AppleScript's text item delimiters to astid
dbText
If the elements of the XML file are guaranteed to be in the required order, there’s no need to go through AppleScript record process. The text value ‘PackageID’ and the list ‘vals’ can be joined together like this to make each DB record line:
set end of dbRecords to {packageID, vals} as Unicode text
The method for turning a list of paired values into a record “
set rec to «class seld» of (record {«class usrf»:labelValuePairs} as record)
“ works in Tiger and is an OS X variation of a method that used to work in OS 8/9:
set labelValuePairs to {"a", 7, "name", "Aardvark", "modification date", current date}
set rec to «class seld» of (record {«class usrf»:labelValuePairs} as record)
--> {a:7, |name|:"Aardvark", |modification date|:date "Thursday 26 April 2007 15:03:18"}
Notice that the labels produced are user labels, not reserved ones. It doesn’t work in Jaguar (I don’t know about Panther) but there’s an alternative that does, using File Read/Write commands:
set labelValuePairs to {"a", 7, "name", "Aardvark", "modification date", current date}
set fRef to (open for access file ((path to trash as Unicode text) & "Test.dat") with write permission)
try
set eof fRef to 0
write {«class usrf»:labelValuePairs} to fRef
set rec to (read fRef from 1 as record)
end try
close access fRef
rec
--> {a:7, |name|:"Aardvark", |modification date|:date "Thursday 26 April 2007 15:03:18"}
The inverse of this, which only works with user labels, appears to be:
set rec to {a:7, |name|:"Aardvark", |modification date|:date "Thursday 26 April 2007 15:03:18"}
set fRef to (open for access file ((path to trash as Unicode text) & "Test.dat") with write permission)
try
set eof fRef to 0
write rec to fRef
set labelValuePairs to (read fRef from 13 as list)
end try
close access fRef
labelValuePairs
--> {"a", 7, "name", "Aardvark", "modification date", date "Thursday 26 April 2007 15:03:18"}