NSXMLParser example
Asked Answered
A

3

10

I have an XML like this

<IS>
    <Value>
        <Signature>-804</Signature>
        <Amount>139</Amount>
    </Value>
    <Value>
        <Signature>-845</Signature>
        <Amount>639466</Amount>
    </Value>
    <Value>
        <Signature>-811</Signature>
        <Amount>16438344</Amount>
    </Value>
    <Value>
        <Signature>-1115</Signature>
        <Amount>-159733</Amount>
    </Value>
</IS>

Now I want to parse only specific values from this. For example, how do I get the value for the node having corresponding signature as -804

Please help me..

I know the basics of NSXMLParser, but do not know how to acheive conditional parsing.

Thank you.

Add answered 16/1, 2011 at 13:26 Comment(3)
Are you only ever going to be interested in a specific element, rather than the document contents as a whole?Devito
yes, I need to parse only specific node value (kind of conditional as i told earlier)Add
In that case NSXMLParser probably isn't the best match for your requirements - see my answer for the full info.Devito
E
10
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
    currentKey = nil;
    [currentStringValue release];
    currentStringValue = nil;
    if([elementName isEqualToString:@"Value"]){
        //alloc some object to parse value into
    } else if([elementName isEqualToString:@"Signature"]){
        currentKey = @"Signature";
        return;
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
    if(currentKey){
        if(!currentStringValue){
            currentStringValue = [[NSMutableString alloc] initWithCapacity:200];
        }
        [currentStringValue appendString:string];
    }
}

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
    if([elementName isEqualToString:@"Signature"] && [currentStringValue intValue] == 804){
        ivar.signature = [currentStringValue intValue];
        return;
    }
}

Something like this. Note I havent really tested this code on compiler so there will be syntax errors here & there.

Export answered 16/1, 2011 at 15:3 Comment(1)
This seems to be more easier for me to implement. However I have one question...Actually I am looking for the string stored in <Amount> corresponding to the <Signature> element i.e I need to get the <Amount> text for <Signature> having -804 Not sure if your example will do that.Add
D
6

You may want to look into using TouchXML - https://github.com/mrevilme/TouchXML which offers some nice XML handling features including the use of XPATH which makes what you are trying to do much simpler.

A hypothetical example based on your model:

//first, load an XML document
CXMLDocument *xmlDoc = [[CXMLDocument alloc] initWithXMLString:someXMLString options:0 error:&error];

//get node
CXMLNode *amountNode = [xmlDoc nodeForXPath:@"//Value[@Signature='-804']/Amount" error:&error];

//or get actual value of node
NSSString *amountString =  = [[xmlDoc nodeForXPath:@"//Value[@Signature='-804']/Amount" error:&error] stringValue];

Note: None of these exapmles are tested.

I have found TouchXML very useful and compact.

Hope this helps.

Drawer answered 18/1, 2011 at 19:30 Comment(0)
D
4

There are effectively two approaches to parsing XML - an event driven one (such as that used by NSXMLParser) and a tree approach (such as that used by NSXML).

If you're only after specific elements, then it would probably be a lot easier to use the tree approach used by NSXML as it'll enable you to query XML documents using XPath (and indeed XQuery) to return specific nodes, etc. that you're interested in.

If this sounds like it might be a more fruitful approach that using NSXMLParser to iterate over the whole structure, then I'd recommend reading the Introduction to Tree-Based XML Programming Guide for Cocoa. (The "Querying an XML Document" section should be of particular interest.)

Devito answered 16/1, 2011 at 13:41 Comment(8)
So if I use NSXMLm I can achieve conditional parsing as I want. Do you have any similar example which I can use as reference?Add
@hmthur If you look at the "Querying an XML Document" section of the document I link to above there are code samples included.Devito
Just to confirm, so NSXML is available on IOS? See #3448493Add
@hmthur Arrghh. My apologies - it's not available on iOS. In that case, you probably want to use libxml (it has xpath). See cocoawithlove.com/2008/10/…Devito
libxml is looking way too complicated to use..I mean it is a C-based API, very diff from the Obj-C code I am used to... Do you have some ref example using libxml which does a similar thing that I am looking for..Add
@hmthur The "The implementation" section of the blog I linked to is pretty much perfect as an example (and you can download the code). That said, it is perhaps slightly more complex than using a pure Cocoa implementation if you're not used to using C based APIs.Devito
Is there any way of bypassing this ...like using libxml under the hood, but we need to use Obj-C type calls from the outside...Add
@hmthur Nope - it is was it is. That said, there are other XML libraries available, but I'm not aware off hand if they support xpath. That said, this blog article might prove very useful: raywenderlich.com/553/…Devito

© 2022 - 2024 — McMap. All rights reserved.