PDA

View Full Version : Using a local XML file for parsing - iPhone




Dan Berry
Jun 13, 2008, 01:48 PM
Good afternoon everyone. I am trying to create an application for the iPhone that will use an XML file for it's data source. I have been attempting to convert the SeismicXML application from the dev center to use a locally stored file, but to no avail. I have it building and running fine, but no data is appearing. Is there anyone that can give me an example of parsing with a locally stored file? Thanks!



forrestgrant
Jun 24, 2008, 08:41 AM
Hey there, I am attempting to do the same thing... did you have any luck?

pluto456
Jun 24, 2008, 10:05 PM
I'm a n00b to iPhone programming and found it a real PITA to get an XML parser working. After piecing together things from various Google searches, here's what I got to work:



#import <Foundation/Foundation.h>
#import <Foundation/NSXMLParser.h>

- (void)parserDidStartDocument:(NSXMLParser *)parser{
NSLog(@"found file and started parsing");
}

- (void)parseXMLFileAtURL:(NSString *)URL //URL is the file path (i.e. /Applications/MyExample.app/MyFile.xml)
{
//you must then convert the path to a proper NSURL or it won't work
NSURL *xmlURL = [NSURL fileURLWithPath:URL];

// here, for some reason you have to use NSClassFromString when trying to alloc NSXMLParser, otherwise you will get an object not found error
// this may be necessary only for the toolchain
NSXMLParser *parser = [[ NSClassFromString(@"NSXMLParser") alloc] initWithContentsOfURL:xmlURL];

// Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
[parser setDelegate:self];

// Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];

[parser parse];

[parser release];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
NSLog(@"found this element: %@", elementName);
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
}


Some other key points:
- having a bad XML file will also cause your parser to not work. This means unclosed tags, or not having the xml declaration at the top, like: "<?xml version="1.0" encoding="UTF-8"?>"
- also, you need to include some other stuff when you compile. Otherwise it will compile just fine, but won't parse anything. This is my include list: "-lobjc -framework CoreFoundation -framework Foundation -framework UIKit -framework CoreGraphics -framework GraphicsServices -framework IOKit -framework WebKit -framework LayerKit -framework OfficeImport" IOKit through OfficeImport seem to be necessary. I tried to leave one out and it just doesn't work
- finally, I'm doing all of this with the toolchain, so things might be different with the genuine SDK, but this works for me.

Good luck!

forrestgrant
Jun 25, 2008, 07:23 AM
So I also got it to work, but slightly different. In your XMLReader.m Class, when instantiating the NSXML, use data instead of URL like so:

NSXMLParser *parser = [[NSXMLParser alloc] initWithData:DATA];

Likewise, you need a full local path to the file, but this did the trick for me. How about luck parsing different types of xml, for instance the Seismic App using xml formatted:


<xml>
<data>
<name>Forrest</name>
<age>25</name>
<username>forrestgrant</username>
</data>
</xml>


But the file I want to parse is more like:


<xml>
<data name="Forrest" age="25" username="forrestgrant" />
<other value="6" />
</xml>


I am having a very hard time getting those values... Anyone have any similar problems?

pluto456
Jun 25, 2008, 09:12 AM
attribute values for elements are stored in the attributeDict variable that's passed to parserDidStartElement:
For example, to get the name from your first data element, you would do this:
NSString *myFirstName= [attributeDict valueForKey:@"name"];

Dan Berry
Jun 25, 2008, 11:31 PM
Forest, you said using initWithData worked for you. Where did you store the xml file for the app, and can you tell me what the full path was in your code? Thank you all for your help so far.

Enuratique
Jun 26, 2008, 12:31 AM
Forest, you said using initWithData worked for you. Where did you store the xml file for the app, and can you tell me what the full path was in your code? Thank you all for your help so far.

There's a whole section on Resource Management for the iPhone, but to save you the trouble of finding it on Apple's site - here's what I do. First, with your project open in XCode, right click the Resources folder in the tree on the left, select Add Existing file, select the XML file you want to add and check the Copy to local project folder checkbox (if the XML file doesn't already live with your other code files). This should make it show up in your Resources list along with your xib and plist files. When you build the application, it will bundle it up for you automagically. Then to get its file path in code do this:


NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"myFile.xml"];


HTH,

Enuratique

forrestgrant
Jun 27, 2008, 07:17 AM
Good call, I hadnt noticed that you could use a local path like that. I did things almost exactly the same except my path looked more like:


NSString *file= @"/Users/me/Documents/App/file.xml";


Thanks for the tip.

acanby
Aug 9, 2008, 03:00 AM
thank you so much for this!!!! i have been tearing my hair out all day trying to get this to work.

tadelv
Sep 20, 2008, 06:44 AM
Hello everyone!
This is my first post here on MacRumors Forums, so please be gentle:)

I have problem with the NSXMLParser class in my app for iPhone. I am trying to parse a file from an URL and it seems that the file does not have a valid xml starting tag: "<?xml version="1.0" encoding="UTF-8"?>" that is. So the parser aborts and crashes my app.

I have tried to open the file to a string with initWithContentsOfURL... and appending the start tag at the beginning, but the weird thing is, that when i try to open the file to a string, i get a weird message from the server instead of the xml file...

What are the possibilites of opening the xml with an NSData object and then appending the start tag to this object?

Thanks for helping me out here!:apple:

mbarron
Apr 8, 2009, 09:43 AM
http://codesofa.com/blog/archive/2008/07/23/make-nsxmlparser-your-friend.html

I used and absolute path to XML file starting /Users
at distribution this would be changed to AppDirectory I assume.

Mark

taronga
Sep 27, 2009, 02:51 PM
Is it possible to have an iPhone app import an XML file received in an email?

drivefast
Sep 27, 2009, 04:08 PM
if your app goes and fetches the email itself from the server, yes it is possible. not easy, but possible. but if you're asking about reading the emails that the iphone native email app received, no, you dont have access to those emails.

PhoneyDeveloper
Sep 27, 2009, 04:33 PM
It might be possible for the user to copy the text from mail.app and paste it into your app. Cumbersome but might work.