xml processing or parsing, what to use?

Hi,

I want an applescript that takes a xml file and a xslt file and makes a xhtml file of it.
(I don’t know which is the correct name for it, xml processing or parsing?)

I know the java library Saxon can do this http://saxon.sourceforge.net/
Can I make a script that communicates with a java library via shell commands?

Or is it easier to use XML Tools from late night software? http://www.latenightsw.com/freeware/XMLTools2/
I looked in it dictionary, but I can’t find anything to make my html file with.

Or is it something else I need to use for this?
It must support XSLT 2.0

Anybody can help me out here?

I found the XMLLib.osax which should do what I need. However, I don’t really understand its dictionairy sow I don’t know how to exactly use it

I’ve tried this:


set xsltFile to "/Users/jonasyde/Dropbox/School/Eindwerk/Probeersels_XSLT/Werkmap/XMP_omvormen.xslt"
set xmlFile to "/Users/jonasyde/Dropbox/School/Eindwerk/Probeersels_XSLT/Werkmap/sample_file_esko.xml"
set outputpath to "/Users/jonasyde/Desktop/output.html"
XMLTransform xmlFile with xsltFile in outputpath

and this: (looking to an example in the online dictionary i found here: http://www.satimage.fr/software/en/dictionaries/dict_xmllib.html)


set xsltFile to XMLOpen "/Users/jonasyde/Dropbox/School/Eindwerk/Probeersels_XSLT/Werkmap/XMP_omvormen.xslt"
set xmlFile to XMLOpen "/Users/jonasyde/Dropbox/School/Eindwerk/Probeersels_XSLT/Werkmap/sample_file_esko.xml"
set outputpath to "/Users/jonasyde/Desktop/output.html"
XMLTransform xmlFile with xsltFile in outputpath

both time the error is that het doesn’t understand the XMLOpen or XMLTransform command.
The osax is correctly installed because XMLOpen and XMLTransform are displayed blue instead of green when I execute the script.

Anybody can help me?

It would be nice to see the exact error messages you saw, but I think I found the problem anyway.

The first place to look should always be the dictionary entries for the commands and classes involved (the documentation that you found is an online version of the dictionary that you can see by using the FIle > Open Dictionary. (⇧⌘O) in Script Editor). The dictionary entry for XMLTransform says that it needs an XMLRef as its direct parameter, and that the with parameter can either be a string (the XSLT itself”not a pathname!) or an another XMLRef. XMLOpen can produce the required XMLRef object(s), so let us look at its dictionary entry. It says that the direct parameter to XMLOpen should be an alias or a string containing the XML itself (not a pathname!).

In your first script, you were passing a string (a POSIX pathname) to both the direct and with parameters of XMLTransform. The direct parameter should have been an XMLRef, so you probably got an error there. The second problem here is that the string you are giving to the with parameter is not the XSLT document itself, but a POSIX pathname of a file containing the XSLT.

In your second script, you used XMLOpen to create XMLRef objects, which is a step in the right direction. The problem here is the same as the second problem with the first script: you are providing a string value that is a POSIX pathname when the command is expecting any string be the XML data. The primary expected value for the direct parameter to XMLRef is alias, so I would go with that instead by making an alias from the pathname (POSIX file pathnameVar as alias).

When I change the paths, the following script worked on the tiny XML+XSLT example I had at hand.

set xsltFile to "/Users/jonasyde/Dropbox/School/Eindwerk/Probeersels_XSLT/Werkmap/XMP_omvormen.xslt"
set xmlFile to "/Users/jonasyde/Dropbox/School/Eindwerk/Probeersels_XSLT/Werkmap/sample_file_esko.xml"
set outputpath to "/Users/jonasyde/Desktop/output.html"

XMLTransform (XMLOpen (POSIX file xmlFile as alias)) with (XMLOpen (POSIX file xsltFile as alias)) in POSIX file outputpath

Model: iBook G4 933
AppleScript: 1.10.7
Browser: Safari 4.0.4 (4531.21.10, r53456)
Operating System: Mac OS X (10.4)

Thanks a lot for your explanation, I understand the dictionary much better now.

When I use your example script I still get an error:


error "file \"Macintosh HD:Users:jonasyde:Dropbox:School:Eindwerk:Probeersels_XSLT:Werkmap:sample_file_esko.xml\" kan niet in type alias worden omgezet." number -1700 from file "Macintosh HD:Users:jonasyde:Dropbox:School:Eindwerk:Probeersels_XSLT:Werkmap:sample_file_esko.xml" to alias

The error message seems to translate into English as “file “.” can not be converted into type alias”, which is probably the same as the English version “Can’t make file “.” into type alias.”. I get the same error number (and the equivalent English message) when the path does not refer to an existing file. Check your xmlFile pathname to be sure all the components are exactly the same as they are on the drive.

As an alternative, you could use choose file to make sure you have a valid file.

-- works with the previously posted code:
.
set xmlFile to POSIX path of choose file with prompt "Choose an XML file:"
.
-- change the previously posted code a bit to avoid converting to and from a POSIX path:
.
set xmlFileAlias to choose file with prompt "Choose an XML file:"
.
. (XMLOpen xmlFileAlias) . -- instead of (XMLOpen (POSIX file xmlFile as alias))

I’ve tried both your solutions, but none seems to be working.


set xmlFile to POSIX path of (choose file with prompt "Choose an XML file:")
set xsltFile to POSIX path of (choose file with prompt "Choose an XSLT file:")
set outputpath to "/Users/jonasyde/Desktop/output.html"

XMLTransform (XMLOpen (POSIX file xmlFile as alias)) with (XMLOpen (POSIX file xsltFile as alias)) in POSIX file outputpath


set xmlFile to choose file with prompt "Choose an XML file:"
set xsltFile to choose file with prompt "Choose an XSLT file:"
set outputpath to "/Users/jonasyde/Desktop/output.html"

XMLTransform (XMLOpen xmlFile) with (XMLOpen xsltFile) in POSIX file outputpath

both times I get the following error:


error "alias \"Macintosh HD:Users:jonasyde:Dropbox:School:Eindwerk:Probeersels_XSLT:Werkmap:sample_file_esko.xml\" begrijpt het XMLOpen-bericht niet." number -1708 from alias "Macintosh HD:Users:jonasyde:Dropbox:School:Eindwerk:Probeersels_XSLT:Werkmap:sample_file_esko.xml"

Translated in english, it says that the file alias does not understand the XMLOpen message.

again, according to me the osax file is correctly installed (I placed it in /Library/ScriptingAdditions

That is the normal installation location, but I would guess that there is something amiss with your installation. After I add set outputpath to “/tmp/foo.xmllib.out” (since I do not have a /Users/jonasyde/), both of those scripts (the ones using choose file) work for me. I am surely running a different versions of the software than you are, however. I am running on Mac OS X 10.4.11 with XMLLib 2.8.7 (it came with an old version of Smile that I installed a long time ago).

Perhaps you are running Snow Leopard”where AppleScript Editor defaults to 64-bit mode”but your XMLLib does not include support for the x84_64 architecture? This might happen if the system was upgraded from or migrated from Tiger or Leopard (with a non-64-bit version of XMLLib installed) to Snow Leopard. The ideal solution would be to install a version of XMLLib that supports both i386 and x86_64. You might be able to work around the problem by running AppleScript Editor in 32-bit mode (selected by a checkbox in its Finder Get Info window, I think). The problem with dropping back to 32-bit mode is that you have to apply the same fix to any applets/droplets you save, and running saved scripts through the script menu may not work correctly (since the execution context of scripts launched from the script menu is not easily switchable to 32-bit mode).

What is the result of the following script?

POSIX path of (path to scripting additions folder from local domain as alias)
result & "XMLLib.osax/Contents/MacOS/XMLLib"
do shell script "file " & quoted form of result

For maximum Snow Leopard compatibility, you want both i386 and x86_64 support (any ppc support is useless and harmless).
For Leopard or Tiger, you will want ppc, or i386 (which ever your hardware uses or both).
The only other likely value is ppc64, but I do not think there was ever a 64-bit version of AppleScript for PPC machines, so it would be useless for an OSAX to support it.

gives:


"/Users/jonasyde/Desktop/XMLLib.osax/Contents/MacOS/XMLLib: Mach-O universal binary with 2 architectures
/Users/jonasyde/Desktop/XMLLib.osax/Contents/MacOS/XMLLib (for architecture ppc):	Mach-O bundle ppc
/Users/jonasyde/Desktop/XMLLib.osax/Contents/MacOS/XMLLib (for architecture i386):	Mach-O bundle i386"

So, you are right. My XMLLib does not support 64 bit. I would never have figured this out on my own, thanks!

The script works when I run it in 32bit mode.

I’ve installed the latest version of smile now, and I now I have a version of XMLLib who supports 64bit


"/Library/ScriptingAdditions/XMLLib.osax/Contents/MacOS/XMLLib: Mach-O universal binary with 3 architectures
/Library/ScriptingAdditions/XMLLib.osax/Contents/MacOS/XMLLib (for architecture i386):	Mach-O bundle i386
/Library/ScriptingAdditions/XMLLib.osax/Contents/MacOS/XMLLib (for architecture ppc7400):	Mach-O bundle ppc
/Library/ScriptingAdditions/XMLLib.osax/Contents/MacOS/XMLLib (for architecture x86_64):	Mach-O 64-bit bundle x86_64"

Now all works as expected. Thanks again for all the help!

Problems keep on coming.
Now I’m having problems implementing it into a bigger script.

the following code works:


on open (xmlFile) --acties bij gebruik als droplet
	parseXML(xmlFile)
end open

on run --acties bij gewoon gebruik
	set xmlFile to (choose file with prompt "Choose an XML file:" without invisibles)
	parseXML(xmlFile)
end run


on parseXML(xmlFile)
	set mePathPOSIX to POSIX path of (path to me)
	set xsltPathPOSIX to mePathPOSIX & "Contents/Resources/XMP_omvormen.xslt"
	--set xsltPathHKS to (xsltPathPOSIX as alias)
	
	set outputpath to "/Users/jonasyde/Desktop/output.html"
	XMLTransform (XMLOpen xmlFile) with (XMLOpen xsltPathPOSIX) in POSIX file outputpath
end parseXML

But when I try to use it in a bigger script, it doesn’t:



on open (theFiles) --acties bij gebruik als droplet
	extractXMP(theFiles)
end open

on run --acties bij gewoon gebruik
	set theFiles to (choose file with multiple selections allowed without invisibles)
	extractXMP(theFiles)
end run

on extractXMP(theFileList)
	repeat with theFile in theFileList
		
		--naam en pad opslaan
		set POSIXFilePath to POSIX path of theFile
		set theFileName to name of (info for theFile)
		set baseDir to POSIX file (do shell script "/usr/bin/dirname " & quoted form of POSIXFilePath) as text
		--exiftool commando opstellen en uitvoeren
		set mePathPOSIX to POSIX path of (path to me)
		set exiftoolPath to mePathPOSIX & "Contents/Resources/exiftool"
		set theShellCommand to quoted form of exiftoolPath & " -XMP -b" & space & quoted form of POSIXFilePath
		set theXMPcontents to do shell script theShellCommand
		
		if theXMPcontents is not equal to "" then
			--xmp bestand schrijven
			set outputPathXML to baseDir & ":" & text 1 thru -4 of theFileName & "xml"
			set textFile to open for access file outputPathXML with write permission
			try
				set eof of textFile to 0
				write theXMPcontents to textFile
				close access textFile
			on error e
				close file outputPathXML
				display dialog e
			end try
			set outputPathHTML to baseDir & ":" & text 1 thru -4 of theFileName & "html"
			set xsltPathPOSIX to mePathPOSIX & "Contents/Resources/XMP_omvormen.xslt"
			XMLTransform (XMLOpen outputPathXML) with (XMLOpen xsltPathPOSIX) in POSIX file outputPathHTML	
		else
			display dialog "Er zit geen XMP file in " & theFileNameChopped
		end if
		
	end repeat
end extractXMP

When I use this script, the xml file is created on my desktop, but the HTML file is not.
I don’t get an error.
The paths to the xslt file is fine.

the source file is wrong in the XMLTransform line. It should be


XMLTransform (XMLOpen theFile) with (XMLOpen xsltPathPOSIX) in POSIX file outputPathHTML  

I diden’t really explain the purpose of my script, and i think i should have.
You must drop a pdf file on de droplet. Then the droplet uses exiftool to get the xmp metadata of the PDF.
These metadata is in XML format. The script writes the xml to an xml file.
That xml file is then transformed with the xslt file to an html file.

theFile in the script is a reference to the pdf file, not the xml file, so it doesn’t work.

I get this error:


error "In file: file://localhost/Users/jonasyde/Desktop/sample_file.pdf
in line 1
Start tag expected, '<' not found
" number 4 from {1, "In file: file://localhost/Users/jonasyde/Desktop/sample_file.pdf
in line 1
Start tag expected, '<' not found
"}

Also, when I use


XMLTransform (XMLOpen textFile) with (XMLOpen xsltPathPOSIX) in POSIX file outputPathHTML

I get the following error:


error "Bestandsverwijzingsnummerfout." number -51

I don’t know the correct english word, but litterly translated et means something like “Filereferencenumberfault”

OK, gotcha, then try


 XMLTransform (XMLOpen alias outputPathXML) with (XMLOpen xsltPathPOSIX) in POSIX file outputPathHTML  

When I used your suggestion, I got my xml file, but no html file.

But then I found the html file, it was on the root of my HD, and its filename was the POSIX path I specified.
Then I remembered I had a similar problem before and the problem was I used a POSIX path when I needed to use a HFS path.

So I used the following code and it worked!


XMLTransform (XMLOpen outputPathXML) with (XMLOpen xsltPathPOSIX) in file outputPathHTML

Thanks for all the help!