NSXMLParser: синтаксический анализ XML с двухуровневой глубиной в приложении для iOS - PullRequest
0 голосов
/ 13 марта 2012

Я застрял на проблеме парсинга XML с удаленного сервера с использованием NSXMLParser.XML-структура выглядит следующим образом:

<data>
    <sale id="example01">
        <article>
            <id>123</id>
            <title>Some title</title>
            <teaser>Some text</teaser>
        </article>
        <article>
            <id>124</id>
            <title>Some title</title>
            <teaser>Some text</teaser>
        </article>
    </sale>
    <sale id="example02">
        <article>
            <id>125</id>
            <title>Some title</title>
            <teaser>Some text</teaser>
        </article>
        <article>
            <id>126</id>
            <title>Some title</title>
            <teaser>Some text</teaser>
        </article>
    </sale>
</data>

Я успешно проанализировал XML и сохранил его в своей CoreDataModel, но кажется, что анализатор захватывает только первый элемент «продажа» и статьи внутри.Когда дело доходит до следующего элемента «продажа», анализатор останавливается без ошибки.Я часто использую NSXMLParser для анализа удаленных данных из XML, но я не могу понять, как решить эту проблему.Для меня важно получить атрибут от продаж, потому что мне нужно создать TableView, в котором элемент "sale" представляет раздел, а статьи определяют ячейки внутри.

В документации сказано, что может быть толькоодин корневой элемент, но не мой корневой элемент?

РЕДАКТИРОВАТЬ # 1: Вот часть кода, который я использовал:

"Verkauf" - это объект DataObject, привязанный к объекту новостей в моей CoreDataModel:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName 
    attributes:(NSDictionary *)attributeDict {


    // If it's the start of the XML, remove everything we've stored so far
    if([elementName isEqualToString:@"daten"])
    {
        [self emptyDataContext];
    }

// Create a new Article

    NSLog(@"Processing Element: %@", elementName);

    if ([elementName isEqualToString:@"article"]) 
    {
        appDelegate.saleArticles = [[NSMutableArray alloc] init];
        currentArticle = (Verkauf *)[NSEntityDescription insertNewObjectForEntityForName:@"Verkauf" inManagedObjectContext:managedObjectContext];

        return;
    }
}

Установите значение элемента:

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 

    if(!currentElementValue) 
        currentElementValue = [[NSMutableString alloc] initWithString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
    else
        [currentElementValue appendString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];

    NSLog(@"Processing Value: %@" ,currentElementValue);

}

Установите значение элемента и добавьте его в CoreData Model:

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

    // !!! This is never called !!!
    if([elementName isEqualToString:@"sale"]){
        NSLog(@"!!!!!!!!!!!!!!Section End!!!!!!!!!!!!!!!!!!!!!!!");
        return;
    }

    // If we're at the end of a county. Save changes to object model
    if ([elementName isEqualToString:@"article"]) 
    {
        [appDelegate.saleArticles addObject:currentArticle];
        // Sanity check
        if(currentArticle != nil)
        {
            NSError *error;

            // Store what we imported already
            if (![managedObjectContext save:&error]) {

                // Handle the error.
                NSLog(@"%@", [error domain]);
            }
        }
        return;
    }
    else if([elementName isEqualToString:@"teaser"]){
        [currentArticle setTeaser:currentElementValue]; 
    }

    else if( ..... };

РЕДАКТИРОВАТЬ # 2: Мой метод инициализации:

- (BOOL)parseXMLFileAtURL:(NSURL *)URL parseError:(NSError **)error
{
    BOOL result = YES;

    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
    // Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
    [parser setDelegate:self];
    // Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
    [parser setShouldProcessNamespaces:NO];
    [parser setShouldReportNamespacePrefixes:NO];
    [parser setShouldResolveExternalEntities:NO];

    [parser parse];

    NSError *parseError = [parser parserError];
    if (parseError && error) {
        *error = parseError;
        result = NO;
    }

    // deactivated because of ARC
    //    [parser release];

    return result;
}

1 Ответ

0 голосов
/ 13 марта 2012

Я не вижу ничего ни в вашем коде, ни в XML (хотя отмечу, что вы, вероятно, англицифицировали XML), поэтому либо я пропустил его (вероятно), либо это что-то странное.

NSXMLParser даст вам больше информации, чем вы предоставили.Метод parse возвращает BOOL.Что это возвращает?Если это NO, вы можете использовать метод parserError, чтобы получить объект NSError, который должен дать вам больше информации.

...