iPhone TBXML Циклы и анализ данных - PullRequest
8 голосов
/ 23 марта 2011

В основном у меня есть ответ XML, который возвращается, и строка, и мне нужно пройтись по xml и сохранить всю информацию в массиве.вот xml

<?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>jonathan.pink@2sms.com</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>

Мне нужны эти 2 <records> и все эти данные, которые будут храниться в массиве.итак ....

массив записей -> массив записей -> массив каждой записи, данные ....

Я сидел здесь, пытаясь решить эту проблему с помощью TBXML, которыйдостаточно просто захватить один узел .... но я не могу этого сделать :(

Ответы [ 4 ]

14 голосов
/ 23 марта 2011

Хорошо, ваш первый шаг - создать класс, который будет анализировать данные. Назовите это RecordParser, например. Теперь нам нужно добавить пару методов в заголовок, а также NSMutableArray.

@interface RecordParser : NSObject {
    NSMutableArray *records;    
}
@property(nonatomic,retain)NSMutableArray *records;

-(void)loadRecords:(NSString *)records;
-(void)traverseElement:(TBXMLElement *)element;

@end

Теперь продолжайте и начните внедрять. Теперь нам нужно реализовать эти два метода, чтобы делать то, что мы хотим, чтобы они делали.

- (void)loadRecords:(NSString *)records {
    NSString *someXML = @"http://www.something.com/somexml.xml";
    TBXML *tbxml = [[TBXML tbxmlWithURL:[NSURL URLWithString:someXML]] retain];

    records = [NSMutableArray array];
    [records retain];

    if (tbxml.rootXMLElement)
        [self traverseElement:tbxml.rootXMLElement];
    [tbxml release];
}

По сути, этот метод захватит соответствующий XML-файл и начнет процесс синтаксического анализа. Кроме того, вы инициализируете свой массив и сохраняете его. Теперь мы подходим к сыру.

- (void) traverseElement:(TBXMLElement *)element {
    do {
        if (element->firstChild) 
            [self traverseElement:element->firstChild];

        if ([[TBXML elementName:element] isEqualToString:@"Record"]) {
            TBXMLElement *destination = [TBXML childElementNamed:@"Destination" parentElement:element];
            TBXMLElement *status = [TBXML childElementNamed:@"Status" parentElement:element];
            TBXMLElement *guid = [TBXML childElementNamed:@"GUID" parentElement:element];
            TBXMLElement *dateSub = [TBXML childElementNamed:@"DateSubmitted" parentElement:element];
            TBXMLElement *dateToSend = [TBXML childElementNamed:@"DateToSend" parentElement:element];
            TBXMLElement *dateSent = [TBXML childElementNamed:@"DateSent" parentElement:element];
            TBXMLElement *dateReceived = [TBXML childElementNamed:@"DateReceived" parentElement:element];
            TBXMLElement *message = [TBXML childElementNamed:@"Message" parentElement:element];
            TBXMLElement *id = [TBXML childElementNamed:@"ID" parentElement:element];

            [records addObject:[NSArray arrayWithObjects:
                                  [TBXML textForElement:destination],
                                  [TBXML textForElement:status],
                                  [TBXML textForElement:guid],
                                  [TBXML textForElement:dateSub],
                                  [TBXML textForElement:dateToSend],
                                  [TBXML textForElement:dateSent],
                                  [TBXML textForElement:dateReceived],
                                  [TBXML textForElement:message],
                                  [TBXML textForElement:id],nil]];  
        }
    } while ((element = element->nextSibling));  
}

По сути, метод выполняет поиск по XML-файлу в поисках элемента с именем, которое вы ищете, а затем захватывает данные из дочерних узлов. Кроме того, данные добавляются в массив records. Таким образом, в основном, когда это сделано, в массиве records должны быть нужные данные, которыми вы можете манипулировать, сколько хотите.

Это полностью не проверено . Не вините меня, если он взорвет ваш компьютер и убьет вашу кошку. Обычно я не взял бы всю работу, чтобы написать полный метод, подобный этому, но мне нравится TBXML. Пожалуйста, дайте мне знать, если это работает. Я действительно был бы признателен за знание.

1 голос
/ 24 июня 2013

Я написал рекурсивную функцию для анализа любого правильно созданного XML с библиотекой TBXML.

В моем проекте у меня есть класс для анализа XML.У него есть метод класса с именем: + (id) infoOfElement: (TBXMLElement *) element

Как использовать:

TBXML *tbxml = [TBXML tbxmlWithXMLData:yourData];
TBXMLElement *rootXMLElement = tbxml.rootXMLElement;

id parsedData = [self infoOfElement: rootXMLElement];

    //return NSString or NSDictionary ot NSArray of parsed data
    + (id) infoOfElement: (TBXMLElement*) element
    {
        if (element->text)
            return [TBXML textForElement:element];
        NSMutableDictionary *info = [NSMutableDictionary new];
        TBXMLAttribute *attribute = element->firstAttribute;
        if (attribute) {
            do {
                [info setValue:[TBXML attributeValue:attribute] forKey:[TBXML attributeName:attribute]];
                attribute = attribute -> next;
            } while (attribute);
        }
        TBXMLElement *child = element->firstChild;
        if (child){
            TBXMLElement *siblingOfChild = child->nextSibling;
            //If we have array of children with equal name -> create array of this elements
            if ([[TBXML elementName:siblingOfChild] isEqualToString:[TBXML elementName:child]]){
                NSMutableArray *children = [NSMutableArray new];
                do {
                    [children addObject:[self infoOfElement:child]];
                    child = child -> nextSibling;
                } while (child);
                return [NSDictionary dictionaryWithObject:children forKey:[TBXML elementName:element]];
            }
            else{
                do {
                    [info setValue:[self infoOfElement:child] forKey:[TBXML elementName:child]];
                    child = child -> nextSibling;
                } while (child);
            }
        }            
        return info;
    }
0 голосов
/ 07 января 2012

Лучше использовать NSXMLParser, потому что это официальный выпуск Apple.

Вся документация по NSXMLParser здесь .

Также вот NSXMLParser учебник .

0 голосов
/ 23 марта 2011

Используйте Apple NSXMLParser; это сделало быть старой школой и все, но это действительно эффективно.

Настройте ваш XMLParser соответствующим образом (используйте протокол NSXMLParserDelegate).

Как только ваш парсер нажмет, перезвоните делегату parser:didStartElement:namespaceURI:qualifiedName:attributes:, и elementName будет равен Record (из того, что вы, похоже, хотите).

Alloc 'init' и NSMutableDictionary. Тогда, как указано выше, если elementName равно Destination, тогда [myDictionary setObject: elementName forKey: @"Destination"] и т. Д.

Надеюсь, это помогло:).

Небольшое примечание: предпочтительнее использовать Apple's «технологию» вместо сторонних: это более эффективно и возможности бесконечны .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...