I’m trying to use NSXMLNode’s objectsForXQuery:error: to return a list of xPaths for nodes of a certain name OR return a list of Xpaths for all the nodes in the XML.
Option 1 example:
Using this XML:
If I just wanted all the nodes with a particular name, I could do:
use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
its getNodes:"/Users/tneison/Desktop/markerTest.fcpxml" forNodesNamed:"marker"
on getNodes:thePath forNodesNamed:targetNode
set aURL to current application's |NSURL|'s fileURLWithPath:thePath -- make NSURL
set theXMLDoc to current application's NSXMLDocument's alloc()'s initWithContentsOfURL:aURL options:0 |error|:(missing value) -- make XMLDoc
set theNodes to theXMLDoc's objectsForXQuery:("//" & targetNode) |error|:(missing value)
current application's NSLog("%@", theNodes)
end getNodes:forNodesNamed:
Which returns:
It would be great if there were a function that did the same thing BUT instead of returning a list of nodes, it returns a list of Xpaths like this:
Option 2 example:
Simply return a list of all the xPaths like so:
Any Ideas as to how I could accomplish either one of these tasks in ASOC?
Don’t confuse what’s logged with what you have – what’s logged is just a description. You have the nodes, so you can call the XPath method on them. If you want it as a single string, use something like this:
set theResult to ((theNodes's valueForKey:"XPath")'s componentsJoinedByString:linefeed) as text
It isn’t exactly what you asked for because it includes the index for every element:
set theResult to ((theNodes's valueForKey:"XPath")'s componentsJoinedByString:linefeed)
set theResult to (theResult's stringByReplacingOccurrencesOfString:"[1]" withString:"") as text
--> "/project/sequence/spine/clip/marker
/project/sequence/spine/clip/marker[2]
/project/sequence/spine/clip/marker[3]
/project/sequence/spine/clip/marker[4]
/project/sequence/spine/clip[2]/marker
/project/sequence/spine/clip[2]/marker[2]
/project/sequence/spine/clip[2]/marker[3]"
Wow. Thanks. That’s pretty easy. I keep forgetting that the array returned is the actual locations in the XMLDocument object. Since that is the case I really don’t need to return the xPath. If I want to modify the value of , I can simply do this:
use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
its editNodeWithName:"marker" atIndex:0 withAttrNamed:"value" replacementString:"This is a new value" inputPath:"/Users/tneison/Desktop/markerTest.fcpxml" saveResultTo:"/Users/tneison/Desktop/markerTest-RESULT.fcpxml"
on editNodeWithName:targetNode atIndex:|index| withAttrNamed:theAttrName replacementString:newString inputPath:thePath saveResultTo:outputPath
set aURL to current application's |NSURL|'s fileURLWithPath:thePath -- make NSURL
set theXMLDoc to current application's NSXMLDocument's alloc()'s initWithContentsOfURL:aURL options:0 |error|:(missing value) -- make XMLDoc
set theNodes to theXMLDoc's objectsForXQuery:("//" & targetNode) |error|:(missing value)
set theTag to theNodes's objectAtIndex:|index|
set theAttr to theTag's attributeForName:theAttrName
theAttr's setStringValue:newString
set theXMLData to theXMLDoc's XMLDataWithOptions:(current application's NSXMLNodePrettyPrint)
theXMLData's writeToFile:outputPath atomically:true
end editNodeWithName:atIndex:withAttrNamed:replacementString:inputPath:saveResultTo: