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.

copenndthagen
  • 49,230
  • 102
  • 290
  • 442

3 Answers3

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.

skywinder
  • 21,291
  • 15
  • 93
  • 123
Asad Khan
  • 11,469
  • 13
  • 44
  • 59
  • This seems to be more easier for me to implement. However I have one question...Actually I am looking for the string stored in corresponding to the element i.e I need to get the text for having -804 Not sure if your example will do that. – copenndthagen Jan 16 '11 at 17:42
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.

dredful
  • 4,378
  • 2
  • 35
  • 54
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.)

John Parker
  • 54,048
  • 11
  • 129
  • 129
  • 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? – copenndthagen Jan 16 '11 at 13:44
  • @hmthur If you look at the "Querying an XML Document" section of the document I link to above there are code samples included. – John Parker Jan 16 '11 at 13:47
  • Just to confirm, so NSXML is available on IOS? See http://stackoverflow.com/questions/3447993/how-to-parse-such-kind-of-data-using-nsxml-parsing – copenndthagen Jan 16 '11 at 13:55
  • @hmthur Arrghh. My apologies - it's not available on iOS. In that case, you probably want to use libxml (it has xpath). See http://cocoawithlove.com/2008/10/using-libxml2-for-parsing-and-xpath.html – John Parker Jan 16 '11 at 13:59
  • 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.. – copenndthagen Jan 16 '11 at 18:27
  • @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. – John Parker Jan 16 '11 at 18:33
  • 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... – copenndthagen Jan 16 '11 at 18:46
  • @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: http://www.raywenderlich.com/553/how-to-chose-the-best-xml-parser-for-your-iphone-project – John Parker Jan 16 '11 at 21:35