I just want to ask, if it is possible to use NSXMLParser object with the new AS Objective-C libraries?
I have tried to use the delegate, the same way I have tried to use NSUserNotificationCenter, but it is not doing system error, it simply on parse method returns false and the methods, which žshould" be called, are never called.
-- Created 2013-12-07 14:13:20 +0100 by Petr Sourek
-- DJManas
use AppleScript version "2.3"
use scripting additions
use framework "Foundation"
-- use framework "AppKit"
-- use framework "WebKit"
on parseXML()
set theXMLParser to current application's NSXMLParser's alloc()'s initWithContentsOfURL:(current application's NSURL's fileURLWithPath:"/Macintosh HD/Users/djmanas/Library/Caches/TemporaryItems/Pozpatku - Doug Naylor copy.epub/Refactor/OEBPS/content.opf")
theXMLParser's setDelegate:me
if theXMLParser's parse() is equal to false then log ("Not Wokring")
theXMLParser's release()
end parseXML
on parserDidStartDocument:_parser
log ("Start")
end parserDidStartDocument:
on parserDidEndDocument:_parser
log ("End")
end parserDidEndDocument:
on parser:_parser didStartElement:_element namespaceURI:_nameSpace qualifiedName:_qName attributes:_attrs
log (_element)
end parser:didStartElement:namespaceURI:qualifiedName:attributes:
on parser:_parser didEndElement:_element namespaceURI:_nameSpace qualifiedName:_qName
log (_element)
end parser:didEndElement:namespaceURI:qualifiedName:
on parser:_parser parseErrorOccurred:_error
log (_error's code() & " " & _error's localizedDescription())
end parser:parseErrorOccurred:
on parser:_parser validationErrorOccurred:_error
end parser:validationErrorOccurred:
on parser:_parser foundCharacters:_foundChars
end parser:foundCharacters:
It uses Arc, so the release line should induce an error. And by the way, you can of course also use NSXMLParser for tree based parsing, instead of event driven. I prefer that personally, since the code tends to be a lot less complex then (the delegates).
Edit
“Tree based XML programming Guide” is the title to search for in the Documentation of XCode.
To be honest, I am using it to parse simple file with ePub information (opf file), I don’t need anything fancy, just get some metadata info like book name, author name and put back some alterations in the epub structure (like move all pictures to Folder/Pictures/*) and this should be rewritten in the file and I dont want to do it manually
By the way, I could have used System Events, but it is way to slow, even though I don’t want something fancy.
I stuck with something like this and it works like a charm, thanks again guys
-- Init the file and contents
if theOpfFile contains ":" then
set my _opfFile to (POSIX path of theOpfFile) as text
else
set my _opfFile to theOpfFile as text
end if
set my _contentsOfFile to NSXMLDocument's alloc()'s initWithContentsOfURL:(NSURL's fileURLWithPath:(my _opfFile)) options:(current application's NSXMLNodePreserveWhitespace) |error|:(missing value)
set my _rootElement to my _contentsOfFile's rootElement()
on getValForTag(theValues)
-- Local vars
local theValues, defaultValues, _tag, _attr, _element, _subElement, _subAttr
-- Default values
set defaultValues to {tag:"", attr:""}
set theValues to theValues & defaultValues
-- For better reading
set _tag to tag of theValues
set _attr to attr of theValues
repeat with _element in my _rootElement's children()
repeat with _subElement in _element's children()
if _subElement's |name|() as text is equal to _tag and _attr is equal to "" then
return _subElement's stringValue() as text
else if _subElement's |name|() as text is equal to _tag and _attr is not equal to "" then
repeat with _subAttr in _subElement's attributes()
if _subAttr's stringValue() as text is equal to _attr then
return _subElement's stringValue() as text
end if
end repeat
end if
end repeat
end repeat
return false
end getValForTag
Don’t forget you have XPath. NSXMLDocument’s implementation doesn’t support namespaces well, but it might be useful:
set theXMLDoc to current application's NSXMLDocument's alloc()'s initWithContentsOfURL:aURL options:0 |error|:(missing value) -- make XMLDoc
set {theResults, theError} to (theXMLDoc's nodesForXPath:theQuery |error|:(reference)) -- query
if theResults is not missing value then
repeat with aNode in (theResults as list)
I guess that using XPath from ASOC leads to speed improvements in the code, as for Objective-C it is faster to walk the tree. This follows the same principle as much else: as long as you use what is in Cocoa and the like, like XPath, then you should be able to stay close to performance of Objective-C.
As long as bulk and other operations happens behind the scenes, it doesn’t matter where.
Another thing is, that NSXML, together with the overview of how to bind up XML towards table views and the like, as discussed in tree based XML Programming guide (maybe Shane’s book cover it), should really be a big cherry when developing ASOC “Table based Apps”.
Without any licensing fees or payments for runtime-engine, if you prefer to pay with some hours.
Maybe it’s because I’m not fully awake but I don’t understand what is supposed to call the handler
on getValForTag(theValues)
in the script embedded in message #6.
He just provided the core and meat of what you need. You’ll need to either call the handler somewhat reworked by passing the docRoot, or you’d remove the signature and the end statement of the handler, and work it into the run handler. It is a great example really, and he stated that he used something like this.
By the way, the truly fastest way to parse an XML file, at least from Objective-C is to use the event driven approach, and that shouldn’t be to hard, if the structure of the XML is fairly shallow, without too many levels of nesting (and the content of course being well defined).