Handling Parsing Errors

When the parser encounters a syntactical error or any other problem in an XML document that prevents it from being well-formed, it stops parsing and sends a message to its delegate. The delegate, if it implements the parser:parseErrorOccurred: method, receives this message. In its implementation it should display a message informing users what the problem is. The parsing error is fatal (that is, unrecoverable) so informing the user is all that you can realistically accomplish. With this information, the user might be able to fix the XML so the document can be successfully parsed.

Listing 1 illustrates how you might implement parser:parseErrorOccurred:.

Listing 1  Handling parsing errors

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    NSWindow *modWin = [self windowForSheet];
    if (!modWin) modWin = [NSApp mainWindow];
    NSAlert *parserAlert = [[NSAlert alloc] init];
    [parserAlert setMessageText:@"Parsing Error!"];
    [parserAlert setInformativeText:[NSString stringWithFormat:@"Error %i,
        Description: %@, Line: %i, Column: %i", [parseError code],
        [[parser parserError] localizedDescription], [parser lineNumber],
        [parser columnNumber]]];
    [parserAlert addButtonWithTitle:@"OK"];
    [parserAlert beginSheetModalForWindow:modWin modalDelegate:self
        didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
        contextInfo:nil];
    [parserAlert release];
}
 
- (void)alertDidEnd:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo { }

The key line in this example is the one that constructs the NSAlert object’s informative text. This text includes the error code (an NSXMLParserErrorenum constant), a localized description of the error, and a line number and column (nesting level) number isolating the location of the error in the XML document. In the example, the delegate obtains this information from two different sources: from the parser object itself (provided in the first parameter of the method) or from the NSError object provided in the second parameter. From the parser object it can also get an NSError object, and from that it can get a localized description.

However, the default localized description of NSError is rudimentary. You might want to provide your own localized description instead of relying on the one obtained from the NSError object. Sometimes parsing errors may require an application-specific interpretation. To implement a function or method for this purpose, you can use the NSXMLParserError constant defining the error to determine which custom key to use in the NSLocalizedString macro. (Of course, you must also create a strings file and do whatever else is necessary to internationalize your application.)