Пример NSXMLParser

У меня есть такой XML

<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>

Теперь я хочу анализировать только определенные значения из этого. Например, как мне получить значение для node, имеющего соответствующую подпись как -804

Пожалуйста, помогите мне..

Я знаю основы NSXMLParser, но не знаю, как добиться условного синтаксического анализа.

Спасибо.

Ответ 1

- (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;
    }
}

Что-то вроде этого. Примечание. Я действительно не тестировал этот код в компиляторе, поэтому здесь и там будут синтаксические ошибки.

Ответ 2

Возможно, вы захотите изучить TouchXML - https://github.com/mrevilme/TouchXML, который предлагает некоторые хорошие функции обработки XML, включая использование XPATH, который делает то, что вы пытаетесь сделать проще.

Гипотетический пример, основанный на вашей модели:

//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];

Примечание. Ни один из этих exapmles не протестирован.

Я нашел TouchXML очень полезным и компактным.

Надеюсь, что это поможет.

Ответ 3

Существует два подхода к анализу XML - управляемый событиями (например, используемый NSXMLParser) и древовидный подход (например, используемый NSXML).

Если вы только после определенных элементов, то, вероятно, будет намного проще использовать подход дерева, используемый NSXML, поскольку он позволит вам запрашивать XML-документы с помощью XPath (и даже XQuery) для возврата определенных узлов, и т.д., которые вас интересуют.

Если это похоже на более плодотворный подход, который использует NSXMLParser для перебора всей структуры, я бы рекомендовал прочитать Введение в Tree- Руководство по программированию на основе XML для Cocoa. (Раздел "Запрос XML-документа" должен представлять особый интерес.)