System Events make XML

Hi,

Is there a way to make an xml file using System Events’ XML Suite? It doesn’t work the same as the Property List Suite. Or is there something else built in to do this? Otherwise, third party XML Tools osax works.

Thanks,
kel

You could always use AppleScriptObjC. More verbose, but more flexible. For example:

set xmlElement to current application's NSXMLNode's elementWithName_stringValue_("some_element", "Blah blah")
set xmlDoc to current application's NSXMLDocument's alloc()'s initWithRootElement_(xmlElement)
xmlDoc's setCharacterEncoding_("UTF-8")
xmlDoc's setVersion_("1.0")
set theData to xmlDoc's XMLData()
theData's writeToFile_atomically_("/Users/shane/Desktop/SomeXML.xml", true)

Hi Shane,

I ran your script using ASObjC Runner with this:

script MakeXML
	set XMLElement to current application's NSXMLNode's elementWithName_stringValue_("some_element", "Blah blah")
	set xmlDoc to current application's NSXMLDocument's alloc()'s initWithRootElement_(XMLElement)
	xmlDoc's setCharacterEncoding_("UTF-8")
	xmlDoc's setVersion_("1.0")
	set theData to xmlDoc's XMLData()
	theData's writeToFile_atomically_("/Users/kelhome/Desktop/SomeXML.xml", true)
end script

tell application "ASObjC Runner"
	set the_result to run the script {MakeXML} with response
end tell
the_result

and got an error:

Note that I changed the desktop path.

Thanks,
kel

It’s working OK here. I wonder if there’s a terminology conflict with some scripting addition. Does any of the script appear styled other than green (or whatever color you use for variables) or black, apart from the true and current application bits?

Hi Shane,

Yes, the XMLElement is blue. I’ll try it with vertical bars.

Edited: that was it! You’re a genius. :smiley:
ps. I can’t wait to try the versatility.

Edited: it’s a conflict with XMLLib which I think is from Satimage.

Thanks a lot,
kel

Changing the name to something like theElement might be tidier than pipes. Terminology conflicts are the curse of scripting additions, particularly where they use common single-word terms.

XML stuff can take a while to get the hang of, but the main classes apart from NSXMLDocument are XMLNode and XMLElement (which is a subclass of XMLNode).

Hi Shane,

Yes, It is tricky and I’m probably trying to do the easy part. :slight_smile:

Can you give me a jumpstart and tell me how to put one element in another. I managed to do the pretty printing part which took hours. :slight_smile: At least I learned about constants. Here’s how I tried to put one element in another:

script MakeXML
	set theXMLElement1 to current application's NSXMLNode's elementWithName_stringValue_("root", "Replace this.")
	set theXMLElement2 to current application's NSXMLNode's elementWithName_stringValue_("level1", "Replace this also")
	-- how to insert Element2 into Element1?
	theXMLElement1's setObjectValue_(theXMLElement2)
	set xmlDoc to current application's NSXMLDocument's alloc()'s initWithRootElement_(theXMLElement1)
	xmlDoc's setVersion_("1.0")
	xmlDoc's setCharacterEncoding_("UTF-8")
	set theData to xmlDoc's XMLDataWithOptions_(current application's NSXMLNodePrettyPrint)
	theData's writeToFile_atomically_("/Users/kelhome/Desktop/SomeXML.xml", true)
	return result
end script

tell application "ASObjC Runner"
	set the_result to run the script {MakeXML} with response
end tell
the_result

→ From file → <?xml version="1.0" encoding="UTF-8" standalone="no"?>
Replace this also

Edited: I think maybe i need to use the string value of theXMLElement2?

Edited: no that wasn’t it.

Edited: I see it I think. Somehting with setChild. Maybe I should rest my brain.

Edited: wonder if I need to initialize a node within the node. This is confusing.

Thanks,
kel

You use insertChild_atIndex_:

	theXMLElement1's insertChild_atIndex_(theXMLElement2, 1) -- zero-based

Hi Shane,

I figured it out with addChild:

script MakeXML
	set theXMLElement1 to current application's NSXMLNode's elementWithName_("root")
	set theXMLElement2 to current application's NSXMLNode's elementWithName_stringValue_("level1", "Replace this also")
	-- how to insert Element2 into Element1?
	theXMLElement1's addChild_(theXMLElement2)
	set xmlDoc to current application's NSXMLDocument's alloc()'s initWithRootElement_(theXMLElement1)
	xmlDoc's setVersion_("1.0")
	xmlDoc's setCharacterEncoding_("UTF-8")
	set theData to xmlDoc's XMLDataWithOptions_(current application's NSXMLNodePrettyPrint)
	theData's writeToFile_atomically_("/Users/kelhome/Desktop/SomeXML.xml", true)
	return result
end script

tell application "ASObjC Runner"
	set the_result to run the script {MakeXML} with response
end tell
the_result

Thanks for the start,
kel

Yep. insertChild_atIndex_ gives you control over order.