How can I parse this xml using GDataXML parser?

5.5k views Asked by At
<list>
    <OrderData HASH="1408108039"></OrderData>
    <OrderData HASH="208524692">
        <id>97</id>
        <customer>
            <CustomerData HASH="2128670187"></CustomerData></customer>
        <billingAddress></billingAddress><deliveryAddress></deliveryAddress>
        <orderDetail>
            <list>
                <OrderDetailData HASH="516790072"></OrderDetailData>
                <OrderDetailData HASH="11226247"></OrderDetailData>
                <OrderDetailData HASH="11226247"></OrderDetailData>
            </list>
        </orderDetail>
        <log/>
    </OrderData>
    <OrderData HASH="1502226778"></OrderData>
</list>

I cannot find a solution to find the number of OrderDetailData elements? I also read http://iphonebyradix.blogspot.com/2011/03/using-gdata-to-parse-xml-file.html this url.

Thanks in advance.

Edit:

I am explaining my requirement again. In this xml there will be multiple OrderData element. Now I have to count the number of OrderDetailData elemnts from a particular OrderData element. Suppose that, according to my xml, the current parsed xml has one OrderData element, named id and its value is 97. Now, I have to count how many OrderDetailData elements are contained in the OrderData(whichid` is 97).

4

There are 4 answers

2
Lorenzo B On BEST ANSWER

This is a simple example how to retrieve some data. This example is very simple and not use XPath expression. I suggest you first understand how it works and then use XPath expression. In my opinion it is not useful to use XPath expression if you cannot understand how the parser works.

NSString* path = [[NSBundle mainBundle] pathForResource:@"test2" ofType:@"xml"];

NSData *xmlData = [[NSMutableData alloc] initWithContentsOfFile:path];
NSError *error;
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData 
                                                       options:0 error:&error];
//NSLog(@"%@", doc.rootElement); // print the whole xml

NSArray *orderDataArray = [doc.rootElement elementsForName:@"OrderData"];

for (GDataXMLElement *orderDataElement in orderDataArray) {

    if([orderDataElement childCount] > 0)
    {            
        NSString *attributeForOrderDataElement = [(GDataXMLElement *) [orderDataElement attributeForName:@"HASH"] stringValue];   

        NSLog(@"attributeForOrderDataElement has value %@", attributeForOrderDataElement);

        GDataXMLElement* idElement = (GDataXMLElement*)[[orderDataElement elementsForName:@"id"] objectAtIndex:0];

        NSLog(@"id has value %@", idElement.stringValue);

        GDataXMLElement* orderDetailElement = (GDataXMLElement*)[[orderDataElement elementsForName:@"orderDetail"] objectAtIndex:0];

        GDataXMLElement* listElement = (GDataXMLElement*)[[orderDetailElement elementsForName:@"list"] objectAtIndex:0];            

        NSArray* orderDetailDataArray = [listElement elementsForName:@"OrderDetailData"];

        int count = 0;
        for (GDataXMLElement *orderDetailDataElement in orderDetailDataArray) {

            NSString *attributeForOrderDetailDataElement = [(GDataXMLElement *) [orderDetailDataElement attributeForName:@"HASH"] stringValue];

            NSLog(@"attributeForOrderDetailDataElement has value %@", attributeForOrderDetailDataElement);

            count++;
        }

        NSLog(@"%d", count);
    }
}

[doc release];
[xmlData release]; 

This is the output console:

attributeForOrderDataElement has value 208524692 <-- HASH value
id has value 97 <-- id value
attributeForOrderDetailDataElement has value 516790072 <-- HASH value
attributeForOrderDetailDataElement has value 11226247
attributeForOrderDetailDataElement has value 11226247
3 <-- the count

Hope it helps.

Edit

test2.xml contains your file but you could pass it as a string. You can also pass as parameters as string like the following:

NSString* xmlString = @"<list>"
    "<OrderData HASH=\"1408108039\"></OrderData>"
    "<OrderData HASH=\"208524692\">"
    "<id>97</id>"
    "<customer>"
    "<CustomerData HASH=\"2128670187\"></CustomerData>"
    "</customer>"
    "<billingAddress></billingAddress>"
    "<deliveryAddress></deliveryAddress>"
    "<orderDetail>"
    "<list>"
    "<OrderDetailData HASH=\"516790072\"></OrderDetailData>"
    "<OrderDetailData HASH=\"11226247\"></OrderDetailData>"
    "<OrderDetailData HASH=\"11226247\"></OrderDetailData>"
    "</list>"
    "</orderDetail>"
    "<log/>"
    "</OrderData>"
    "<OrderData HASH=\"1502226778\"></OrderData>"
    "</list>";    

GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithXMLString:xmlString options:0 error:&error];  
6
vishy On

If the OrderDetailData is present in 2nd object of array all the time, u can use the below

NSArray* arr = [[XMLelement elementForName:@"list"] elementsForName:@"OrderData"];    
NSXMLElement* listElement = [[[arr objectAtIndex:1] elementForName:@"orderDetail"] elementForName:@"list"];
NSArray* orderDetailArray* = [listElement elementsForName:@"OrderDetailData"];

In this u can get the OrderDetailData elements in the array, and u can parse the data in loop. to get HASH value use.

NSString* hash = [[orderDetailArray objectAtIndex:0] stringValueForAttribute:@"HASH"];
0
Shefali Soni On

I found TouchXML easy in parsing and you can directly access data needed from xml

First of all Download TouchXML and add libxml2.dylib framework to your project. change buildsetting for "Header Search Path" and add "/usr/include/libxml2" Import TouchXML.h to your file

//Access document 
CXMLDocument *parserDoc = [[CXMLDocument alloc] initWithContentsOfURL:url options:0 error:&err];

//Access root element and access children in heirarchy
CXMLElement *root = [parserDoc rootElement];
NSArray *places = [[[root children] objectAtIndex:0] children];

Else

//Access node by node
NSString *location =[[[[[parserDoc nodesForXPath:@"/xml_api_reply/weather/forecast_information/city" error:nil] objectAtIndex:0] attributeForName:@"data"] stringValue] retain];
0
vishy On

This is the below code, i have tried. I got the right output.. check out

NSString* xmlString = @"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                       "<list>"
                       "<OrderData HASH=\"1408108039\"></OrderData>"
                       "<OrderData HASH=\"208524692\">"
                       "<id>97</id>"
                       "<customer>"
                       "<CustomerData HASH=\"2128670187\"></CustomerData></customer>"
                       "<billingAddress></billingAddress><deliveryAddress></deliveryAddress>"
                       "<orderDetail>"
                       "<list>"
                       "<OrderDetailData HASH=\"516790072\"></OrderDetailData>"
                       "<OrderDetailData HASH=\"11226247\"></OrderDetailData>"
                       "<OrderDetailData HASH=\"11226247\"></OrderDetailData>"
                       "</list>"
                       "</orderDetail>"
                       "<log/></OrderData>"
                       "<OrderData HASH=\"1502226778\"></OrderData>"
                       "</list>";

NSXMLDocument*  doc = [[NSXMLDocument alloc] initWithData:[xmlString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
NSXMLElement* rootElement = [doc rootElement];

NSArray* arr = [rootElement elementsForName:@"OrderData"];
NSXMLElement* orderDataElement;

for (int i = 0; i < [arr count]; i++)
{
    int Id = 0;
    Id = [[arr objectAtIndex:i] integerValueForNode:@"id"];
    if (Id != 0)
    {
        orderDataElement = [arr objectAtIndex:i];
        break;
    }
}

NSArray* orderDetailArray = [[[orderDataElement elementForName:@"orderDetail"] 
                              elementForName:@"list"] 
                             elementsForName:@"OrderDetailData"];

for (int j = 0; j < [orderDetailArray count]; j++)
{
    NSLog(@"%@", [[orderDetailArray objectAtIndex:j] stringValueForAttribute:@"HASH"]);
}