ophychius
ophychius

Reputation: 2653

NSXMLParser does not finish file

I am parsing an XML file in my app and the oddest thing happens. It stops after a number of elements, not finishing that element yet the parse method still returns succes. I have the feeling it is a wrong character somewhere but cannot figure it out. Does anyone have any idea why it halts during the parsing. And why, if it doesn't finish the file does it return true for being done parsing?

File that parses:

MOOAnimal *soort;
NSString *currentElementValue;


- (void) getData
{
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"soorten" ofType:@"xml"];  

    NSURL *xmlUrl = [NSURL fileURLWithPath:filePath];

    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:xmlUrl];

    [parser setDelegate:self];

    BOOL succes = [parser parse];


    if(succes)
    {
        data = true;
        beestjes = [NSArray arrayWithArray:soorten];
    }


}

- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if([elementName isEqualToString:@"soorten"])
    {
        soorten = [[NSMutableArray alloc] init ];
    }
    else if([elementName isEqualToString:@"soort"])
    {
        soort = [[MOOAnimal alloc] init];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    currentElementValue = nil;
    currentElementValue = [[NSString alloc] initWithString:string];
     NSLog(@"Naam: %@", currentElementValue);
}

- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if([elementName isEqualToString:@"soorten"])
    {

    }
    else if([elementName isEqualToString:@"soort"])
    {
        [soorten addObject: soort];
        soort = nil;
    }
    else if([elementName isEqualToString:@"nl"])
    {
        [soort setName:currentElementValue];

    }
}

The XML file:

<soorten>
<soort><wormscode>117644</wormscode><localnames><nl>Ruwe zeerasp </nl></localnames><latinname>Hydractinia echinata </latinname><omschrijving></omschrijving><opmerkingen></opmerkingen></soort>
<soort><wormscode>231751</wormscode><localnames><nl>Haringgraat </nl></localnames><latinname>Halecium halecinum </latinname><omschrijving></omschrijving><opmerkingen></opmerkingen></soort>
<soort><wormscode>117273</wormscode><localnames><nl>Lampenkapje  </nl></localnames><latinname>Aequorea vitrina</latinname><omschrijving></omschrijving><opmerkingen></opmerkingen></soort>
<soort><wormscode>125333</wormscode><localnames><nl>Dodemansduim  </nl></localnames><latinname>Alcyonium digitatum</latinname><omschrijving></omschrijving><opmerkingen></opmerkingen></soort>
<soort><wormscode>283798</wormscode><localnames><nl>Viltkokeranemoon </nl></localnames><latinname>Cerianthus lloydii </latinname><omschrijving></omschrijving><opmerkingen></opmerkingen></soort>
<soort><wormscode>100803</wormscode><localnames><nl>Rode paardeanemoon </nl></localnames><latinname>Actinia equina </latinname><omschrijving></omschrijving><opmerkingen></opmerkingen></soort>
<soort><wormscode>100834</wormscode><localnames><nl>Zeedahlia  </nl></localnames><latinname>Urticina felina</latinname><omschrijving>- Doorsnede van de zuil en de voetschijf niet groter dan 10 tot 15 cm. De hoogte circa 6 cm. De tentakels tot 2 cm hoog.
- Een Zeedahlia is een grote brede zeeanemoon met korte dikke tentakels.
- Kenmerkend is de helder gekleurde tekening op de mondschijf. Deze bestaat uit dubbele lijnen die vanaf de mond gezien vóór de tentakels beginnen.
- Vrijwel alleen op hard substraat zoals stenen maar soms ook op veen of onder veenranden. Af en toe op pontons. De soort wordt aangetroffen vanaf iets boven de laagwaterlijn tot diepten van 15 meter en meer.
- Algemeen  in het Nederlandse zoute water.</omschrijving><opmerkingen></opmerkingen></soort>
<soort><wormscode>100872</wormscode><localnames><nl>Golfbrekeranemoon  </nl></localnames><latinname>Diadumene cincta</latinname><omschrijving></omschrijving><opmerkingen></opmerkingen></soort>
<soort><wormscode>395099</wormscode><localnames><nl>Groene golfbrekeranemoon  </nl></localnames><latinname>Haliplanella lineata</latinname><omschrijving></omschrijving><opmerkingen></opmerkingen></soort>
</soorten>

Where it stalls (by logging all the data/characters found)

2012-06-07 10:49:31.654 MOOFormulier[27852:f803] Naam: 
2012-06-07 10:49:31.654 MOOFormulier[27852:f803] Naam: 283798
2012-06-07 10:49:31.655 MOOFormulier[27852:f803] Naam: Viltkokeranemoon 
2012-06-07 10:49:31.655 MOOFormulier[27852:f803] Naam: Cerianthus lloydii 
2012-06-07 10:49:31.655 MOOFormulier[27852:f803] Naam: 
2012-06-07 10:49:31.656 MOOFormulier[27852:f803] Naam: 100803
2012-06-07 10:49:31.656 MOOFormulier[27852:f803] Naam: Rode paardeanemoon 
2012-06-07 10:49:31.657 MOOFormulier[27852:f803] Naam: Actinia equina 
2012-06-07 10:49:31.657 MOOFormulier[27852:f803] Naam: 
2012-06-07 10:49:31.658 MOOFormulier[27852:f803] Naam: 100834
2012-06-07 10:49:31.658 MOOFormulier[27852:f803] Naam: Zeedahlia  
2012-06-07 10:49:31.659 MOOFormulier[27852:f803] Naam: Urticina felina
2012-06-07 10:49:31.659 MOOFormulier[27852:f803] Naam: - Doorsnede van de zuil en de voetschijf niet groter dan 10 tot 15 cm. De hoogte circa 6 cm. De tentakels tot 2 cm hoog.

Upvotes: 0

Views: 147

Answers (2)

ophychius
ophychius

Reputation: 2653

A colleague who also looked into the problem pointed out I did not define a character set in a tag at the beginning of the file. This caused the parser to trip over certain unique characters in the file. With that set it works fine now.

Credit goes to my colleague who I still need to convert to a StackOverflow user.

Upvotes: 0

Luca Corti
Luca Corti

Reputation: 545

In parser:foundCharacters: you should append string to currentElementValue, not overwrite the whole string. Also log your values in parser:didEndElement:

NSMutableString *currentElementValue;
[...]

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    currentElementValue = [NSMutableString new];
    [...]
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
     NSLog(@"Element: %@ Value: %@",elementName, currentElementValue);
    [currentElementValue release];
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    [currentElementValue appendString:string];
}

Upvotes: 1

Related Questions