Фильтрация символов спецификации из NSXMLDocument

Строковые значения некоторых элементов из XML-файлов содержат в себе символы спецификации. Файл xml помечен как кодировка UTF-8.

Некоторые из этих символов находятся в начале строки (как и должно быть из того, что я читал об этом), но некоторые находятся в середине строки (возможно, искаженная строка от того, кто написал файл xml?).

Я открываю файл с помощью:

NSURL *furl = [NSURL fileURLWithPath:fileName];
if (!furl) {
    NSLog(@"Error: Can't open NML file '%@'.", fileName);

    return kNxADbReaderTTError;
}

NSError *err=nil;

NSXMLDocument *xmlDoc = [[NSXMLDocument alloc] initWithContentsOfURL:furl options:NSXMLNodeOptionsNone error:&err];

И я запрашиваю элемент следующим образом:

NSXMLElement *anElement;
NSString *name;
...
NSString *valueString = [[anElement attributeForName:name] stringValue];

Мои вопросы:

Я неправильно открываю файл? Файл имеет неправильный формат? Я неправильно запрашиваю строковое значение элемента? Как я могу отфильтровать эти символы?


person Damien Sirkis    schedule 06.11.2012    source источник


Ответы (1)


При устранении другой проблемы я нашел относительно чистый способ фильтрации нежелательных символов из источника NSXMLDocument. Вставьте его сюда на всякий случай, если кто-то столкнется с подобной проблемой:

@implementation NSXMLDocument (FilterIllegalCharacters)

    - (NSXMLDocument *)initWithDataAndIgnoreIllegalCharacters:(NSData *)data illegalChars:(NSCharacterSet *)illegalChars error:(NSError **)error{
    // -- Then, read the resulting XML string.
    NSMutableString *str = [[NSMutableString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    // -- Go through the XML, only caring about attribute value strings
    NSMutableArray *charactersToRemove = [NSMutableArray array];
    NSUInteger openQuotes = NSNotFound;
    for (NSUInteger pos = 0; pos < str.length; ++pos) {
        NSUInteger currentChar = [str characterAtIndex:pos];

        if (currentChar == '\"') {
            if (openQuotes == NSNotFound) {
                openQuotes = pos;
            }
            else {

                openQuotes = NSNotFound;
            }
        }
        else if (openQuotes != NSNotFound) {
            // -- If we find an illegal character, we make a note of its position.
            if ([illegalChars characterIsMember:currentChar]) {
                [charactersToRemove addObject:[NSNumber numberWithLong:pos]];
            }
        }
    }

    if (charactersToRemove.count) {
        NSUInteger index = charactersToRemove.count;

        // -- If we have characters to fix, we work thru them backwards, in order to not mess up our saved positions by modifying the XML.
        do {
            --index;

            NSNumber *characterPos = charactersToRemove[index];
            [str replaceCharactersInRange:NSMakeRange(characterPos.longValue, 1) withString:@""];
        }
        while (index > 0);

        // -- Finally we update the data with our corrected version
        data = [str dataUsingEncoding:NSUTF8StringEncoding];
    }

    return [[NSXMLDocument alloc] initWithData:data options:NSXMLNodeOptionsNone 

    error:error];
}

@end

Вы можете передать любой набор символов, который хотите. Обратите внимание, что при этом параметры чтения XML-документа устанавливаются равными нулю. Возможно, вы захотите изменить это для своих целей.

Это фильтрует только содержимое строк атрибутов, откуда и взялась моя неверная строка.

person Damien Sirkis    schedule 11.07.2013