0
votes

i stuck on a problem parsing an XML from remote server using NSXMLParser. The XML-structure looks like this:

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

I successfully parsed the XML and stored it into my CoreDataModel, but it seems like the parser only grabs the first "sale" element and the articles within. When it comes to the next "sale" element, the parser stops, without an error. I often use NSXMLParser for parsing remote Data from XML, but I can't figure out how to solve this problem. It's important for me to get the attribute from sales, cause I have to create a TableView in which the "sale" element represents the Section and the articles define the Cells within.

The documentation says that there could only be one root element, but isn't my root element?

EDIT#1: Here is some of the Code I used:

"Verkauf" is the DataObject Bound to the News-Entitiy in my 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;
    }
}

Set element value:

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

}

Set the Value of Element and add it to 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( ..... };

EDIT#2: My Init Method:

- (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
You'll probably have to post some of your code. There's nothing odd about the XML as far as I can see.Stephen Darlington

1 Answers

0
votes

I don't see anything in either your code or the XML (though I note that you've probably Anglicised the XML), so either I missed it (likely) or it's something weird.

NSXMLParser will give you more information than you've provided. The parse method returns a BOOL. What is it returning? If it's a NO you can use the parserError method to get an NSError object that should give you more information.