How to get a DTD's public and system IDs with NSXMLParser - objective-c

I'm trying to retrieve the public and system IDs for a DTD in an XML document via NSXMLParser. While NSXMLParser in principal offers publicID and systemID selectors they don't seem to work for me. The doctype tag looks like this:
<!DOCTYPE Article PUBLIC "-//SoftQuad Software//DTD Journalist v2.0 20000501//EN" "file:///C:/Program%20Files/Corel/XMetaL%204/Author/Rules/journalist.dtd">
Here's my code (the file was opened via NSFileHandle's readDataToEndOfFile:
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
[parser setDelegate:self];
BOOL parseSuccessful = [parser parse];
In the delegate's parserDidStartDocument: I try to access the IDs:
NSLog(#"%# : %#", [parser publicID], [parser systemID]);
But I only see
(null) : (null)
From the documentation:
You may invoke this method once a parsing operation has begun or after an error occurs.
So I'd think this should work already in parserDidStartDocument: but I tried to call these selectors in different delegate methods (like parser:didStartElement:namespaceURI:qualifiedName:attributes: but without success.
Any ideas what I'm doing wrong?

You might try out another parser.
http://www.robbiehanson.com/expat.html provides a drop-in replacement for NSXMLParser based on expat.
You might also find this article interesting, comparing the performance of various XML parsers on the iPhone.
http://www.raywenderlich.com/553/how-to-chose-the-best-xml-parser-for-your-iphone-project

Related

Objective-C RSS Reader - XML reading error

I am new to obj-C and i'm trying to make an easy RSS Reader. It works with an external RSS file but not when i load the same file in my server based on AWS services.
This is the snippet code:
[super viewDidLoad];
feeds = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:#"http://images.apple.com/main/rss/hotnews/hotnews.rss"];
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
If i read that rss via web, i see this:
When I upload that file on my server, i see this:
I tried to avoid manual upload via Filezilla but using wget command and i also tried ascii mode transfer, but still not work. RSS Reader show an empty list.
It is the problem with URL. I had the crash with the same code with error
Unable to read data
I replaced code with
feedURL = NSURL(string:"http://images.apple.com/main/rss/hotnews/hotnews.rss#sthash.fuVEonEt.dpuf")!
parser = XMLParser(contentsOf:feedURL as URL)!
parser.delegate = self
parser.parse()
It work fine now.
As suggested by #Larme, it was the App Transport Security Issue How do I load an HTTP URL with App Transport Security enabled in iOS 9? .
This solved my issue!

how to use my imported xml in my objective-c project?

i have this demo xml file:
<trains>
<israel>
<Lehavim>
<lat>31.370201</lat>
<lon>34.798336</lon>
</Lehavim>
<tel-aviv>
<lat>32.073847</lat>
<lon>34.793358</lon>
</tel-aviv>
</israel>
</trains>
loaded to my project using this code:
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *url = [[NSURL alloc] initWithString:#"http://www.amotech.co/trains.xml"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[xmlParser setDelegate:self];
BOOL success = [xmlParser parse];
if(success)
NSLog(#"success");
else
NSLog(#"Error");
}
i need to get my xml into a UITableView - i want to only to show the name of the train station (for example: "Lehavim" in the TableView.
and after i chose one of my table view items - i want to load the current lat and lon data into double objects.
i would like you to help me with this please.
thanks, amir.
Sounds like you need to get the fundamentals first:
This link takes you to the gory details of NSXMLParser directly from apple.
This link shows a fantastic example of how to use the NSXMLParser.
This link offers some simple examples for adding objects to an array.
This link is a very nice tutorial on UITableViewController.
You will need to provide a little elbow grease.
Quite Tip
To save yourself some headaches and to add flexibility to your xml, I recommend you modify your xml structure such that you aren't using your element names as values.
Change:
<trains>
<israel>
<Lehavim>
<lat>31.370201</lat>
<lon>34.798336</lon>
</Lehavim>
<tel-aviv>
<lat>32.073847</lat>
<lon>34.793358</lon>
</tel-aviv>
</israel>
</trains>
to:
<trains>
<train>
<name>israel</name>
<location>
<name>Lehavim</name>
<lat>31.370201</lat>
<lon>34.798336</lon>
</location>
<location>
<name>tel-aviv</name>
<lat>32.073847</lat>
<lon>34.793358</lon>
</location>
</train>
</trains>

How to handle the exceptions

NSString *stringURL=[[NSString alloc] init];
stringURL=[stringURL stringByAppendingFormat:kSearchBarURL,text.text];
NSString *url = [NSString stringWithString:stringURL];
NSData *data1 = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
NSString *responseids = [[NSString alloc] initWithData:data1 encoding:nil];
responseids = [responseids stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"\n\r\t"]];
SBJsonParser *parser=[SBJsonParser new];
NSData *data = [parser objectWithString:responseids error:nil];
NSMutableDictionary *searchURL = (NSMutableDictionary*)data;
I coded this i did not handle the exception for my code.
doing json and calling the service url and loading the data.
the application get crashes when my service is too low or no service found.
How to handle the exception for my code here..
Do I use #try #catch.
or
NSURLConnection for error handling.
Please help me out .
Thanks in advance.
Whenever an API makes use of NSError, you should use this rather than wrapping things up in a try…catch block as NSError is designed exactly for this. I usually reserve #try for things where I am really not able to anticipate what might go wrong. If NSError is in the mix, then you know that there is a potential for a problem that you should be handling gracefully.
More generally, your code has some strange stuff in it. You alloc init an empty NSString and then create a new string by appending a format. Not sure why you don't just use [NSString stringWithFormat]. Once you have the string, you can create the URL without the NSString *url bit.
You're also using a synchronous call to what I assume is a remote server. This has the potential to bog down your application if/when the server is not available. You're also not telling NSString what kind of encoding you expect your string to be in when it reads it from NSData. A better method depending on your server side would be to use NSString's stringWithContentsOfURL:usedEncoding:error: method. I would recommend that you use the various NSURLConnection callbacks. Have a look at the URL Loading System Programming Guide on Using NSURLConnection The NSURLConnection delegate methods are the ones you want to implement to provide this asynchronous processing.
For your trimming, you might be interested in the +whitespaceAndNewlineCharacterSet method on NSCharacterSet.
Finally, for your JSON parsing, you might be interested in the category that the SBJSON code adds to NSString, particularly -JSONValue which will give you the dictionary or array representation (as appropriate) of the NSString when parsed as JSON by SBJSON.
HTH

Multiple NSXMLParser calls

I use an API call which returns an XML file. I need to use the same multiple times.
For e.g. on Click of Search button, call http://xyz.com/s1/?para1=srch
Then in a different view, call http://xyz.com/s2/?para2=set2
How should I implement the same? I mean should the XMLParser file be common for both the requests and just the if..else element names should be mixed in a single implementation of parser:didEndElement?
Please help me with an example.
Sure, you can re-use a parser if the page elements are the same. Just make a method in your parser's class that you can feed a location or xml file, and have it parse that file. Something like:
-(void)parseForecast:(NSData *)data; {
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
[parser setDelegate:self];
[parser parse];
[parser release];
}
should do the trick.

parsing JSON using objective C?

I have spent 1 week studying objective C. Now I am quite confused at the dealing with data part.
My friend gave me a link
http://nrj.playsoft.fr/v3/getQuiz.php?udid=23423455&app=2
and ask me write a class to parse this JSON. I had no clue what parsing JSON means. but I have gone online and looked up. I could understand a basics of it and then I impletemented a punch of code to parse this JSON. Which is:
-
(void)parseURL
{
//create new SBJSON object
SBJSON *parser = [[SBJSON alloc] init];
NSError *error = nil;
//perform request from URL
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://nrj.playsoft.fr/v3/getQuiz.php?udid=23423455&app=2"]];
// Perform request and get JSON back as a NSData object
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
// Get JSON as a NSString from NSData response
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
// parse the JSON response into an object
NSDictionary *results = [parser objectWithString:json_string error:&error];
// array just for the "answer" results
NSArray *quizes = [results objectForKey:#"quiz"];
NSDictionary *firstQuiz = [quizes objectAtIndex:0];
// finally, the name key
NSString *extract = [firstQuiz objectForKey:#"extract"];
NSLog(#"this is: %#", [extract valueForKey:#"extract"]);
}
This is at the implementation file, but in the header file I could not declare any variables, it will print out some errors. I tried to run this, there is no errors, but I am not sure this code is correct or not. And my friend asked me to write a class into an existing project. I don't know what needs to be modified and what not. I am so blur right now. Could anyone pro in this give me a hand. ?
My sincere thanks.
Thanks for reply. I have downloading and added the JSON framework ealier too. I am just not sure where to begin and where to end, meaning the step I should do when I add JSON framework into it. I could understand the syntax but I am not sure about the steps I should do. I am a newbie in this.
If you support iOS 5.0+, you should use built-in NSJSONSerialization.
It is faster than TouchJSON.
You could just use TouchJSON: http://code.google.com/p/touchcode/wiki/TouchJSON
Or you could use this one: http://code.google.com/p/json-framework/
I'm sure there are others. I use TouchJSON... it's fast and has a good API.
I recommend working through Ray Wenderlich's MapKit tutorial, especially if you are a newbie. It covers several common iOS development issues, including parsing JSON data.
http://www.raywenderlich.com/2847/introduction-to-mapkit-on-ios-tutorial
"The Implementation" section is where his JSON feed is retrieved and then in "Plotting the Data" he uses the SBJson library to parse it.