2

I have an xml response that i need to set into an array. The problem is i need to access each element and store it in an array so that i can use it for a tableview.

<?xml version="1.0" encoding="UTF-8"?>
<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://schema.2sms.com/2.0/schema/0310_ResponseReportStandard.xsd" Version="1.0">
    <Error>
        <ErrorCode>00</ErrorCode>
        <ErrorReason>OK</ErrorReason>
    </Error>
    <ResponseData>
        <Identification>
            <UserID>[email protected]</UserID>
        </Identification>
        <Result>2 records were returned</Result>
        <Detail>
            <ReportTitle>Message Summary: Today</ReportTitle>
            <Record>
                <Destination>447790686158</Destination>
                <Status>WithNetwork</Status>
                <GUID><![CDATA[2011-03-22T10:54:22.097Z]]></GUID>
                <DateSubmitted>2011-03-22T10:54:22.097</DateSubmitted>
                <DateToSend></DateToSend>
                <DateSent>2011-03-22T10:54:22.533</DateSent>
                <DateReceived></DateReceived>
                <Message><![CDATA[Yet again another test]]></Message>
                <ID>2011-03-22 10:54:22.250HIHIIOJTFVETW85TS</ID>
            </Record>
            <Record>
                <Destination>447790686158</Destination>
                <Status>SUCCESS</Status>
                <GUID><![CDATA[2011-03-22T10:50:40.064Z]]></GUID>
                <DateSubmitted>2011-03-22T10:50:40.063</DateSubmitted>
                <DateToSend></DateToSend>
                <DateSent>2011-03-22T10:50:42.473</DateSent>
                <DateReceived>2011-03-22T10:50:54.570</DateReceived>
                <Message><![CDATA[This is a test]]></Message>
                <ID>2011-03-22 10:50:40.210DRUDVMCEZGETW85TS</ID>
            </Record>
            <ReportPage ReportID="775797" ItemsPerPage="25" Page="1" TotalItems="2" />
        </Detail>
    </ResponseData>
</Response>

I have the TBXML object initialised but can't work out how to get any of the recurring information, I know it will need some sort of loop but i'm pretty new to objective-c so its proving a challenge.

I need to get the <destination> , <status>, <datesent>, <message> from the xml. There can be up to 25 records....

Hope some one can help this has been doing my head in all day!

1 Answer 1

6

I did something similar recently that you can adapt quickly, my XML was:

<?xml version="1.0" encoding="ISO-8859-1"?>
<agencies>
    <agency>
        <name>Agency 1 name</name>
        <addressFirstLine>Immeuble XYZ<addressFirstLine>
        <addressSecondLine>rue de la republique</addressSecondLine>
        <addressThirdLine>69007 Lyon</addressThirdLine>
        <telNumber>01 23 45 67 89</telNumber>
    </agency>
    <agency>
        <name>Agency 2 name</name>
        <addressFirstLine>Immeuble ABC<addressFirstLine>
        <addressSecondLine>rue de la republique</addressSecondLine>
        <addressThirdLine>69007 Lyon</addressThirdLine>
        <telNumber>01 23 45 67 89</telNumber>
    </agency>
</agencies>

The code I used to parse this (get the result in my NSArray called agencies):

    TBXML *tbxml = [[TBXML tbxmlWithXMLFile:yourXmlFile retain];
    TBXMLElement *rootXMLElement = tbxml.rootXMLElement;

    if (rootXMLElement) {
        self.agencies = [self traverseElement:rootXMLElement];
        [delegate managerDidReceiveData];
    }

    // release resources
    [tbxml release];

And my fonction to convert in array:

- (NSArray *)traverseElement:(TBXMLElement *)element {

    NSMutableArray *tmpAgencies = [[NSMutableArray alloc] init];

    TBXMLElement *agenciesXmlElement = element->firstChild;
    TBXMLElement *agencyXmlElement;

    do {

        // if the element has child elements, process them
        if ((agencyXmlElement = agenciesXmlElement->firstChild)) {

            NSMutableDictionary *tmpAgency = [[NSMutableDictionary alloc] init];

            do {
                [tmpAgency setValue:[TBXML textForElement:agencyXmlElement] forKey:[TBXML elementName:agencyXmlElement]];

            // Obtain next sibling element
            } while ((agencyXmlElement = agencyXmlElement->nextSibling));

            [tmpAgencies addObject:tmpAgency];
            [tmpAgency release];
        }

    // Obtain next sibling element
    } while ((agenciesXmlElement = agenciesXmlElement->nextSibling));

    return tmpAgencies;
}

This function will return you an array which contains NSDictionary objects representing your Records. NSDictionary is simple to use, to get a property you use [yourDictionary objectForKey:yourXmlNode]. The doc is here: NSDictionary.

Sign up to request clarification or add additional context in comments.

3 Comments

I've implemented this but the array i get only fills with the anything beyond the second level...
I have only two levels in my sample XML, agenciesXmlElement->firstChild is getting the second level. You have to do this again to go deeply in the levels. You have everything here to do it, just adapt it.
Great answer! But just in case - for n level deepness - gist.github.com/romainbriche/1922643 returns dictionary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.