TBXML root element is null no matter what I do - iphone

Wracking my brain for hours trying to figure this one out. TBXML must have the rootXMLElement set in order to begin traversing and parsing data.
No matter what I do, when I NSLog it, it's null.
Here's a sample of the XML:
<?xml version= "1.0" encoding="UTF8"?>
<patients>
<patient>
<patientNumber>1234</patientNumber>
<nameFirst>Jason</nameFirst>
<!--more properties of a patient-->
</patient>
<patient>
<patientNumber>5542</patientNumber>
<nameFirst>Gary</nameFirst>
<!--more properties of a patient-->
</patient>
</patients>
The code I'm using thus far:
NSURL *xmlURL = [NSURL URLWithString:destPath];
TBXML *tbxml = [TBXML tbxmlWithURL:xmlURL];
NSLog shows tbxml.rootXMLElement as null.
Other details of note:
I use a ruby script to delete any non-ASCII characters from the XML file. The app does not require anything more.
I thought the problem might be that the XML file was not UTF-8, so I used bash command iconv to convert it from ASCII to UTF-8. Didn't work either.
Any suggestions are greatly appreciated.

It looks like it is a local XML based on the fact that you are preprocessing it. When you are processing local file paths as URLs you need to use fileURLWithPath: for it to work properly. So you need to do this,
NSURL *xmlURL = [NSURL fileURLWithPath:destPath];
TBXML *tbxml = [TBXML tbxmlWithURL:xmlURL];

Related

Parse XML in iPhone (attributed not separated)

Is there a way to parse an XML in iOS where the attribute are not separated
e.g:
Users
UserId="1" Name="John Smith" Loc="London"
UserId="2" Name="Johnny Cash" Loc="Nashville"
Users
Thanks
It seams like you havent got xml at all. You are missing all usefully symbols that would normally help with the parsing. You taks is to parse a new format specification.
My first bit of advice is to ask whoever is providing you with this feed to put it into a proper format (JSON or plist are the easiest to work with).
Failing this, if the feed is not too big (otherwise you will hit performance issues), parse the feed manually character by character. You probably want to write a event based parser.
Split the feed line by line, perhaps using componentsSeparatedByString:
Then read characters into a string untill you hit an = that string is your key. Next read between the quotes "" That string is your value. FIre the key and the value off to a delegate.
JSON parsing classes will help you out...
NSString *responseString = #""; // your data contained string.
SBJSON *json = [[SBJSON new] autorelease];
NSArray *resultData = [json objectWithString:responseString error:&error];

libxml2 example (with wrapper)

I am using the XML parser libxml2 with wrapper as given on the page
http://cocoawithlove.com/2008/10/using-libxml2-for-parsing-and-xpath.html
But i am not sure if I am using correctly and am getting errors (parsing,etc)
So could someone please provide me a complete example which i can refer and get an idea if I am doing something incorrectly.
thanks a lot for all your help in advance.
I'm using this methods too, to parse xml and html files.
For example to parse rss xml:
//add xml source
NSURL *url = [NSURL URLWithString:#"http://feeds.bbci.co.uk/news/rss.xml?edition=int"];
NSData *xmlData = [NSData dataWithContentsOfURL:url];
//parse the whole file with all tags
NSArray *rssFeedArray = PerformXMLXPathQuery(xmlData, #"//*");
NSLog(#"rssFeedArray: %#", rssFeedArray);
//* - query means the parser will go through all tags of the file. Then log the array to see the whole structure of xml.
Whith '/rss/channel/item' query you will only get the item tags element's, (or to get only the first item use '/rss/channel/item[1]').
in this case because of the bbc feed structure you can catch each item title at
[[[[rssFeedArray objectAtIndex:i] valueForKey:#"nodeChildArray"] objectAtIndex:0] valueForKey:#"nodeContent"]]
and description at
[[[[rssFeedArray objectAtIndex:i] valueForKey:#"nodeChildArray"] objectAtIndex:1]valueForKey:#"nodeContent"]]
and go on and on.

Having trouble understanding how to work TBXML

I followed the TBXML guide and it's been successfully installed into my code, but the guide they have doesn't make sense to me. I want to get some values from an XML document. An example they have of starting this process is:
TBXML * tbxml = [[TBXML tbxmlWithURL:[NSURL URLWithString:#"http://www.w3schools.com/XML/note.xml"]] retain];
In NSLog, for me this returns:
<TBXML: 0x4e3cc90>
This example XML file contains the following:
<note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don't forget me this weekend!</body></note>
Could somebody give me a quick example on how from this XML file i would be able to extract the <body> of this? Their guide does seem fairly straight forward looking at it, but I just can't seem to make sense of it.
http://www.tbxml.co.uk/TBXML/Guides_-_Loading_an_XML_document.html is their guide.
Andrew,
It appears that once you init TBXML with the xml file, as it appears you have, you then 'traverse' elements in the document using various API. I haven't tested this but it would appear in your example that "body" is a child of "note", therefore... first get the note element and from the root element and extract the body element from the note element.
TBXMLElement *noteElement = [TBXML childElementNamed:#"note" parentElement:rootXMLElement];
TBXMLElement *bodyElement = [TBXML childElementNamed:#"body" parentElement:noteElement];
You should be able to traverse on anything at this point.
-- Frank

NSURL doesn't seem to want to accept my querystring

Hi there I have this code
NSLog(#"%#",URLRequestQueryString);
NSString *sendToServerString = [NSString stringWithFormat:#"http://mydomain.co.uk/req.php%#",URLRequestQueryString];
NSURL *sendToServer = [[NSURL alloc] initWithString:sendToServerString];
NSLog(#"%#",sendToServer);
NSLog(#"%#",sendToServerString);
URLRequestQueryString is just a standard querystring that I have built up throughout the script.
The first NSLog works fine and outputs a proper querystring (if I copy and paste it into a browser then the page will load and run correctly.
This is also the case when I output sendToServerString it correctly outputs the URL with querystring (which I can also copy and paste into a browser).
However sendToServer ouputs (null). If I remove the querystring it will correctly output the domain and path.
Any idea why this happens? How can I sort it?
Thank you.
NSURL *sendToServer = [NSURL URLWithString: [sendToServerString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
Could be what you are looking for. :)
You need see NSString reference.
A Section named "Working with URLs".
Under this section has two method
stringByAddingPercentEscapesUsingEncoding:
stringByReplacingPercentEscapesUsingEncoding:

Encoding issue: Cocoa Error 261?

So I'm fetching a JSON string from a php script in my iPhone app using:
NSURL *baseURL = [NSURL URLWithString:#"test.php"];
NSError *encodeError = [[NSError alloc] init];
NSString *jsonString = [NSString stringWithContentsOfURL:baseURL encoding:NSUTF8StringEncoding error:&encodeError];
NSLog(#"Error: %#", [encodeError localizedDescription]);
NSLog(#"STRING: %#", jsonString);
The JSON string validates when I test the output. Now I'm having an encoding issue. When I fetch a single echo'd line such as:
{ "testKey":"é" }
The JSON parser works fine and I am able to create a valid JSON object. However, when I fetch my 2MB JSON string, I get presented with:
Error: Operation could not be completed. (Cocoa error 261.)
and a Null string. My PHP file is UTF8 itself and I am not using utf8_encode() because that seems to double encode the data since I'm already pulling the data as NSUTF8StringEncoding. Either way, in my single-echo test, it's the approach that allowed me to successfully log \ASDAS style UTF8 escapes when building the JSON object.
What could be causing the error in the case of the larger string?
Also, I'm not sure if it makes a difference, but I'm using the php function addslashes() on my parsed php data to account for quotes and such when building the JSON string.
I'm surprised no one has mentioned using a different encoding value instead of NSUTF8StringEncoding when calling [NSString stringWithContentsOfFile:encoding:error:].
I also got Cocoa error 261 when parsing a JSON file. I just went through the list of NSString encodings until one worked. Fortunately the first one worked for me: NSASCIIStringEncoding!
You can also use NSString stringWithContentsOfFile:usedEncoding:error: to try to find the correct encoding (as described here: How to use stringWithContentsOfURL:encoding:error:?).
Don't know if this is your problem, but I just had a similar thing (stringWithContentsOfFile, no JSON), and the problem was that the file had CRLF (windows) line-endings and Western-whatever-it's-called encoding. I used SubEthaEdit to convert to LF (Mac/Unix line-endings) and UTF-8 encoding, and now everything works fine.
Encoding issue: Cocoa Error 261? I solved this issue by trying different encoding. First I was using NSUTF8 then I switched to NSASCIIStringEncoding and it worked.
NSString* path = [[NSBundle mainBundle] pathForResource: #"fileName" ofType: #"type"];
NSData* data = [NSData dataWithContentsOfFile:path];
NSString *string = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(#"%#",string);
For future reference, if you need to override the encoding, and you're working with streams without embedded NULs, something like this might be good (I've just written a rough sketch outline here, check this code is and does want you want before using it):
NSHTTPURLResponse* resp=nil;
NSData* jsonAsImmutableData = [NSURLConnection sendSynchronousRequest:
[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://<whatever>"]]
returningResponse:&resp error:NULL];
NSMutableData*modifiedData = [NSMutableData dataWithData:jsonAsImmutableData];
char extraNulls[7] =
{0,0,0,0,0,0,0}; // is this defensive enough for your encoding?
[modifiedData appendBytes:extraNulls length:7];
NSString* jsonAsString = [NSString stringWithCString:[modifiedData bytes]
encoding:<whatever your encoding is>];
But I expect your best course of action is to check that your server is both using and claiming to use UTF-8 encoding or some other Apple iPhone supported encoding.
EDIT
altered code comment.
What helped me was just to change the physical file encoding to UTF-8. My editor had set it to the default, MacRoman, and didn't like letters with accents.