Trouble grabbing XML element with nested tags using System Events

Trying to grab an XML element out of an XML file. Sometimes the element has some nested elements in it. If so, then I can’t grab the parent element at all.

set XMLfile to "/path/to/file.xml"
tell application "System Events"
    tell XML element "note" of contents of XML file XMLfile
        set titleText to (the value of XML element "title")
        set bodyText to (the value of XML element "note-content" of XML element "text") as text
        display dialog "Grabbed title " & titleText & " and body " & bodyText
    end tell
end tell

If file.xml is this then it works:

[code]<?xml version="1.0" encoding="utf-8"?>

Title goes here Body goes here. [/code] If it is this then it doesn't work:

[code]<?xml version="1.0" encoding="utf-8"?>

Title goes here Body goes here. [/code] If I omit "as text" then it throws an error saying that bodyText is undefined, but with "as text" it just comes up as an empty string. How can I grab the body text if it contains nested tags?

Hello!

Your xml is malformed. You should remove your / tags first. you can easily do that if you dare!
This is a work around, not helping you with the problem, but telling you what it is.


set XMLfile to "/path/to/file.xml"
tell application "System Events"
	tell XML element "note" of contents of XML file XMLfile
		set titleText to (the value of XML element "title")
		set bodyText to (the value of XML element "note-content" of XML element "text") 
		try
			set probe to bodyText
		on error
			set bodyText to "malformed"
		end try
		display dialog "Grabbed title " & titleText & " and body " & bodyText
	end tell
end tell

I don’t think you can add or use html tags for instance, and expect it to go well, as tags is what xml uses to figure out the structure of your file, if you have such tags, then I suggest you look for other solutions, like in this post maybe this can be done with AsobC runner by the way! post #4

This should work for you:


set XMLfilename to POSIX file "/path/to/file.xml" as text
set thexml to every paragraph of (read file XMLfilename) as text

set titlStart to item 2 of decoupe(thexml, "<title>")
set thetitle to item 1 of decoupe(titlStart, "</title>")
”>Title goes here
set bodyStart to item 2 of decoupe(thexml, "<note-content>")
set thebody to item 1 of decoupe(bodyStart, "</note-content>")
”> Body <i>goes</i> here.
on decoupe(t, d)
	--YVAN KOENIG : http://macscripter.net/viewtopic.php?pid=154203#p154203 
	local oTIDs, l
	set oTIDs to AppleScript's text item delimiters
	set AppleScript's text item delimiters to d
	set l to text items of t
	set AppleScript's text item delimiters to oTIDs
	return l
end decoupe

The problem with system events, is that it seemingly discards whatever text comes before your tag. Well, you could have used the XML Tools from Late Night Software, but why bother really, when the code above does the trick?

Cleaning up the editor, I made a general handler for this. It goes without saying, that you have to know that the tag is there, and it won’t work particularily good I think, if the same tag is nested and such, that is the file is malformed. if the file is empty, or the tag is missing, the handler will return null. It also only works for the cases, when you have only one tagpair of the kind you want to extract from in the file.


set XMLfilename to POSIX file "/path/to/file.xml" as text
set thexml to  (read file XMLfilename) as text

set thetitle to txtBetweenTags(thexml, "<title>")
”>Title goes here

set thebody to txtBetweenTags(thexml, "<note-content>")
”> Body <i>goes</i> here.

on decoupe(t, d)
	--YVAN KOENING : http://macscripter.net/viewtopic.php?pid=154203#p154203 
	local oTIDs, l
	set oTIDs to AppleScript's text item delimiters
	set AppleScript's text item delimiters to d
	set l to text items of t
	set AppleScript's text item delimiters to oTIDs
	return l
end decoupe

to txtBetweenTags(thetext, tag)
	try
		set endTag to "</" & text 2 thru -1 of tag
		set startPhrase to item 2 of decoupe(thetext, tag)
		set theresult to item 1 of decoupe(startPhrase, endTag)
		return theresult
	on error
		return null
	end try
end txtBetweenTags

Edit:And just look away from what I said about “maybe can be done” with the other tools, I have tried to use the XMLlib of Late Night Software, and there were no relief to be found.

The problem with your tags, is that they are not nested in the text, but that xml expects nested tags, so it sort of disrupts the order of the xml, leaving your notecontents, with whats in between your and tags,