|
|||||||
![]() |
|
|
Thread Tools | Search this Thread | Display Modes |
|
|
#1 |
|
AppleScript: Set variable to every XML element of a given name
Dear fellow AppleScript programmers,
I have an iOS app that has recipes. Each recipe can be organized by course or by cuisine. Each course and cuisine have their own table view and controller. I need to make sure each recipe is linked to a course and cuisine. Since a storyboard is really an XML file containing all the UI elements, I figured I could create an AppleScript that searches all the table view cells to make sure that all recipes are linked to two table view cells. Here is my code: Code:
set the_file to ((choose file without invisibles) as string) tell application "System Events" set xml_data to contents of XML file the_file tell xml_data to set tableViewCells to every XML element of xml_data whose name is "tableViewCell" tell xml_data to set subViews to every XML element of tableViewCells whose name is "subviews" tell xml_data to set viewLinks to every XML element of subViews whose name is "view" tell xml_data to set viewControllers to every XML element whose name is "viewController" tell xml_data to set views to every XML element of viewControllers whose name is "view" tell xml_data to set navItems to first XML element of views whose name is "navigationItem" tell xml_data to set recipes to value of XML attribute "title" of XML element navItems end tell I could do the job myself, but I just don't want to.
__________________
Now available on the iPad App Store: Clean Cuisine Click here to load its App Store page. |
|
|
|
0
|
|
|
#2 |
|
What does this error message tell you, or at least what does it suggest to you?
Code:
"Can't get every element of {} whose name = "subviews"".
So work backwards from that, possibly using a debugger. At the very least, you will need to apply the debugging technique of Break It Down. In this case, that means running the script with as few commands as possible, then looking carefully at each result. For example, the starting point is probably something like: Code:
set the_file to ((choose file without invisibles) as string) tell application "System Events" set xml_data to contents of XML file the_file return xml_data end tell Another possibility might be to use some other scripting language that can parse XML, yet gives you better debugging capability. Not sure what you mean by not wanting to do the job yourself. If you're referring to not wanting to find the problem by yourself, then what would someone else need in order to start finding the problem for you? |
|
|
|
0
|
|
|
#3 |
|
Don't use AppleScript for this. The only real use for AppleScript is communicating with applications that support AppleScript. If you have experience with any other programming language that can do XML easily (e.g., Ruby, Python, Perl) you'll find it much simpler, faster, and more robust to write it in that language. My guess is that you'd be able to install any needed XML modules for your chosen language, figure out how to use them, and write, test, and fully debug your program before you got any sort of XML parsing working flawlessly in AppleScript.
Heck, even if you have to learn the entire language starting with "Hello World", you might still be able to do it more quickly than with AppleScript.
|
|
|
|
0
|
|
|
#4 | ||
|
Quote:
---------- Quote:
__________________
Now available on the iPad App Store: Clean Cuisine Click here to load its App Store page. |
|||
|
|
0
|
|
|
#5 | |
|
Quote:
Without the same data, no one can replicate what you're seeing, and no one can explain what you're seeing because no one knows the structure of your XML. So unless you post your actual XML data, no one can explain it. This is what I was trying to get at when I asked you the question, "What would someone else need in order to start finding the problem for you?". The answer is, they would need your XML data. You've already posted your AppleScript code, but without the XML that code is trying to act on, the code by itself is useless. |
||
|
|
0
|
|
|
#6 | |
|
Quote:
Anyways, I'm currently working on some code that will do the trick. I found out that I can tell an XML element to do whatever I want it to. So the code I'm building will accomplish the same task by removing all XML elements except the one it's currently working with, then putting them back in.
__________________
Now available on the iPad App Store: Clean Cuisine Click here to load its App Store page. |
||
|
|
0
|
|
|
#7 | |
|
Quote:
It's up to you to post the code and data that causes the problem. If you want to make (and test) an example XML file with the requisite structure that shows the problem, then please do that and post the fail-case. http://www.mikeash.com/getting_answers.html |
||
|
|
1
|
|
|
#8 |
|
OK, I've hit a roadblock.
Like I said before, I need to isolate one element from the pack at a time. To help me do that, I have a function I can use to remove a piece of text from a string and output the modified string. Obviously, this function doesn't work on XML files. This function is to be called by another function, which will go through all the elements of a given name and tell them to run the code I want them to run. UPDATE: I'm going in the wrong direction.
__________________
Now available on the iPad App Store: Clean Cuisine Click here to load its App Store page. |
|
|
|
0
|
|
|
#9 |
|
Update on my progress toward a solution:
Code:
on removeText(parentString, childString, occurrencesToExclude) set oldDelims to AppleScript's text item delimiters set AppleScript's text item delimiters to childString set textItems to every text item of parentString set AppleScript's text item delimiters to oldDelims if occurrencesToExclude is not missing value then repeat with I from 1 to length of textItems if occurrencesToExclude contains I then set item I of textItems to item I of textItems & childString end if end repeat end if set newString to textItems as string return newString end removeText on tellEveryXMLElementWithName(elementContainer, elementName, code) set XMLContents to (read elementContainer) set newContainer to removeText(XMLContents, elementName, 1) tell elementName run script code end tell end tellEveryXMLElementWithName set the_file to (choose file without invisibles) as string tell application "System Events" set file1 to XML file the_file tell file1 set code to "set X to 0" my tellEveryXMLElementWithName(file1, "tableViewCell", code) end tell end tell
__________________
Now available on the iPad App Store: Clean Cuisine Click here to load its App Store page. |
|
|
|
0
|
|
|
#10 |
|
|
1
|
|
|
#11 |
|
I have Xcode. I just don't want to build a full-on app with GUI and everything, as my script won't be very fancy. I also don't want to download something else to do this.
__________________
Now available on the iPad App Store: Clean Cuisine Click here to load its App Store page. |
|
|
|
0
|
|
|
#12 |
|
You don't have to do any of that. You can write the program in Ruby, Python, or Perl (all of which are already installed on every single Mac out there), and simply execute it from the command line. It doesn't need to have a GUI or anything at all. Or you can easily bake it into an application using Platypus, which lets you turn any program or shell script into a launchable app (with drag and drop support and everything) with just a few clicks. Heck, you can even call AppleScript from within your program, in case you want to use the communication functions or the rudimentary dialog boxes it provides.
AppleScript has its uses. I use it all the time, actually—mainly calling it from within Ruby scripts to automate tedious tasks, much like what you're doing now. But trying to make AppleScript do something outside of the very narrow range of things it's good for is just torturing yourself for no good reason. |
|
|
|
0
|
|
|
#13 |
|
None of which I'm familiar with. I'm not much of a desktop programmer, anyway. I'm more of a Web & mobile app developer. In fact, as I stated, I'm working on a recipe app. I figure this little project may help me in the future, if not right now. I'd do the work myself, but doing the work by hand is boring. Building an app that will do the work for me is fun. And I can share the app with others so they don't have to do that work themselves. (Don't worry, guys, it'll be free of cost and maybe I'll put a GNU GPL on it.)
__________________
Now available on the iPad App Store: Clean Cuisine Click here to load its App Store page. |
|
|
|
0
|
|
|
#14 |
|
No time like the present to learn. Any of those languages would be useful for a web developer, and Ruby can be used to write and deploy mobile apps for iOS. And like I said, if you'd started learning the language back when you first posted about the problem, you'd have it solved by now.
Based on the problem you're describing, we're really only talking about maybe 10 lines of code here.But go ahead and use AppleScript if you really want to. It's just not really well suited for this task. It's a bit like using a hammer to drive a screw—you can probably get it to work, but the result will be ugly, unreliable, and a pain to fix if something goes wrong. |
|
|
|
1
|
![]() |
|
«
Previous Thread
|
Next Thread
»
| Thread Tools | Search this Thread |
| Display Modes | |
|
|
All times are GMT -5. The time now is 03:52 PM.







Based on the problem you're describing, we're really only talking about maybe 10 lines of code here.
Linear Mode
