On 2 Mar 2015, at 12:19 am, Jörgen Stahle <email@hidden> wrote:
Yes I do! Great! My current need is not to make plist-files, but other kinds of xml. But this is easy to adapt.
Right. That's why I say a generic library is difficult -- there are so many variables. For example, here's a small change to what I posted:
on makeXMLDocWithRecord:theRecord -- make root element set rootElement to current application's NSXMLNode's elementWithName:"dict" -- make XML document set theXMLDocument to current application's NSXMLDocument's alloc()'s initWithRootElement:rootElement theXMLDocument's setDocumentContentKind:(current application's NSXMLDocumentXMLKind) theXMLDocument's setStandalone:true theXMLDocument's setCharacterEncoding:"UTF-8" -- make dictionary from record set anNSDictionary to current application's NSDictionary's dictionaryWithDictionary:theRecord -- add children to root element set theKeys to anNSDictionary's allKeys() as list repeat with i from 1 to count of theKeys set theKey to item i of theKeys set newElement to (current application's NSXMLNode's elementWithName:"key" stringValue:theKey) (rootElement's addChild:newElement) set newElement to (current application's NSXMLNode's elementWithName:"string" stringValue:(anNSDictionary's valueForKey:theKey)) (rootElement's addChild:newElement) end repeat -- return as string with whatever formatting options you want return (theXMLDocument's XMLStringWithOptions:(current application's NSXMLNodePrettyPrint)) as text end makeXMLDocWithRecord:
set theRecord to {firstName:"Saga", lastName:"Norén", city:"Malmö"} its makeXMLDocWithRecord:theRecord
Result of Main Script: --> "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?> <character> <firstName>Saga</firstName> <city>Malmö</city> <lastName>Norén</lastName> </character>" I guess it works for nested records/elements as well
Yes, you could do something like this:
use framework "Foundation"
on makeXMLDocWithRecord:theRecord -- make root element set rootElement to current application's NSXMLNode's elementWithName:"character" -- make XML document set theXMLDocument to current application's NSXMLDocument's alloc()'s initWithRootElement:rootElement theXMLDocument's setDocumentContentKind:(current application's NSXMLDocumentXMLKind) theXMLDocument's setStandalone:true theXMLDocument's setCharacterEncoding:"UTF-8" -- make dictionary from record set anNSDictionary to current application's NSDictionary's dictionaryWithDictionary:theRecord -- add children to root element its addChildTo:rootElement withDictionary:anNSDictionary -- return as string with whatever formatting options you want return (theXMLDocument's XMLStringWithOptions:(current application's NSXMLNodePrettyPrint)) as text end makeXMLDocWithRecord:
on addChildTo:parentElement withDictionary:theDict set theKeys to theDict's allKeys() as list repeat with i from 1 to count of theKeys set theKey to item i of theKeys set theValue to (theDict's objectForKey:theKey) set newElement to (current application's NSXMLNode's elementWithName:theKey) (parentElement's addChild:newElement) if (theValue's isKindOfClass:(current application's NSDictionary)) as boolean then (its addChildTo:newElement withDictionary:theValue) else (newElement's setObjectValue:theValue) end if end repeat end addChildTo:withDictionary:
set theRecord to {firstName:"Saga", lastName:"Norén", city:"Malmö", partner:{firstName:"Martin", lastName:"Rohde", city:"København"}} its makeXMLDocWithRecord:theRecord
--> "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?> <character> <firstName>Saga</firstName> <lastName>Norén</lastName> <city>Malmö</city> <partner> <firstName>Martin</firstName> <city>København</city> <lastName>Rohde</lastName> </partner> </character>"
The thing I am missing here is the ability to add attributes to the elements… I guess there is something like addAttribute to use.
Yes, you can use addAttribute:, but in many cases it's probably easier to use setAttributesWithDictionary:, where you pass the attributes as a record/dictionary. But the tricky thing might me how to represent attributes in the record.
You could use a specific key name, such as "attributes". Then modify the second handler like this:
on addChildOrAttributesTo:parentElement withDictionary:theDict set theKeys to theDict's allKeys() as list repeat with i from 1 to count of theKeys set theKey to item i of theKeys set theValue to (theDict's objectForKey:theKey) if theKey as text = "attributes" then (parentElement's setAttributesWithDictionary:theValue) else set newElement to (current application's NSXMLNode's elementWithName:theKey) (parentElement's addChild:newElement) if (theValue's isKindOfClass:(current application's NSDictionary)) as boolean then (its addChildOrAttributesTo:newElement withDictionary:theValue) else (newElement's setObjectValue:theValue) end if end if end repeat end addChildOrAttributesTo:withDictionary:
set theRecord to {firstName:"Saga", lastName:"Norén", city:"Malmö", partner:{firstName:"Martin", lastName:"Rohde", city:"København", attributes:{approach:"dogged"}}} its makeXMLDocWithRecord:theRecord
--> "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?> <character> <firstName>Saga</firstName> <lastName>Norén</lastName> <city>Malmö</city> <partner approach=\"dogged\"> <firstName>Martin</firstName> <lastName>Rohde</lastName> <city>København</city> </partner> </character>"
|