Having trouble understanding how to work TBXML - iphone

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

Related

TBXML root element is null no matter what I do

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];

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.

How to parse complex XML tree using TouchXml in iPhone

I am trying to build an app which during start-up connects to website and downloads the XML data. Though the data is large(100 KB) and i am using TouchXml for it. The xml is like this.
<?xml version="1.0" encoding="UTF-8"?>
<itemA attA="AAA" attB="BBB" attC="CCC">
<itemB>
<itemC1 attD="DDD" attE="EEE" attF="FFF">
<itemD>
<itemE1 attG="GGG">
<itemF>ZZZ</itemF>
<itemG>
<itemH1 attH="HHH">
<itemG>ZZZ</itemG>
<itemH>YYY</itemH>
</itemH1>
<itemH1 attH="III">
...
</itemG>
</itemE1>
...
</itemD>
</itemC1>
...
</itemB>
</itemA>
Here three dots ". . ." presents tens/hundreds of same kind of element. i want to extract each and every attribute and node contents. Initailly i begin with
[CXMLDocument nodesForXPath:#"//itemA" error:nil];
and able to get its attributes and upto first child nodes using -
[CXMLElement childAtIndex:index];
but how i will move further into child nodes and their nodes and get their values. Any help is greatly appreciated.link text
You can use XPaths for this:-
NSArray *nodes = [doc nodesForXPath:#"//itemA/itemB/itemC1" error:nil];
This will return all the nodes in the itemC1 element. Note 'doc' is your CXMLDocument object.
Google XPath for the full syntax.
You would probably definitely be better served with using the event-driven parser in this case; NSXMLParser.

Can't get XML element with colon in the name using TouchXML

I have the following code:
NSString *subtitle = [[[node elementsForName:#"subtitle"] objectAtIndex:0] stringValue];
NSString *duration = [[[node elementsForName:#"itunes:duration"] objectAtIndex:0] stringValue];
The first line works perfectly. The second line though won't work. I assume it has something to do with namespaces, but I'm pretty new to all of this so I would appreciate any guidance. Thank you!
It turns out that I can use the elementsForLocalName:URI: to read the element correctly. Now the problem is that since I am using the TouchXML library, it doesn't seem like that method has been mapped over to the CXMLElement structure (see here).
So the question now is: how can I convert a CXMLElement to an NSXMLElement so that I can use that method?
"itunes" is the namespace identifier. It doesn't actually have any significance on its own, it just links a URI with the element in question. It looks like you're using the iTunes RSS extensions, which live under the namespace http://www.itunes.com/dtds/podcast-1.0.dtd.
So, for namespaced elements, I think (I'm not familiar with Objective-C or NSXML :P) you want to use elementsForLocalName instead:
[node elementsForLocalName: #"duration" URI: #"http://www.itunes.com/dtds/podcast-1.0.dtd"]
For the answer to the second question, see comments below.

get element value

I have a NSString like that? (in iPhone application)
NSString *xmlStr = "<?xml version=1.0 encoding=UTF-8>
<information>
<name>John</name>
<id>435346534</id>
<phone>045635456</phone>
<address>New York</address>
</information>"
How I can get elements value?
(Do i need convert to XML format and get elements value? or split string? any way please tell me?)
Thank you guys.
If you want to use split string, you can use tokenization of strings using "componentsSeparatedByString" method. This is a more cumbersome method of course, rather than the recommended XMLParser
To get the name.
NSArray *xmlStr_first_array = [xmlStr componentsSeparatedByString: #"<name>"];
NSString *xmlStr_split = [NSString stringWithFormat:#"%#",[xmlStr_first_array objectAtIndex:1]];
NSArray *xmlStr_second_array = [xmlStr_split componentsSeparatedByString: #"</name>"];
NSString *name = [NSString stringWithFormat:#"%#",[xmlStr_second_array objectAtIndex:0]];
The most obvious solution is to use an XML parser to retrieve the values from each element.
You could use the excellent TBXML for this task. It provides a really simple interface where it wouldn't take more than a few lines to retrieve the desired values. The drawback to using this small library is that it (as far as I know) loads the entire XML data into memory. In this particular case, however, that is not problem at all.
There's of course also the option of using the NSXMLParser, though this is an event-driven parser, and thus a bit less simple to use.
Your string is in xml format already and you need to parse it to retrieve data. There're several options available - for example you can use NSXMLParser class or libxml library.
Edit: XMLPerformance sample project shows how to use both approaches and compare their performance.