Фильтрация символов спецификации из NSXMLDocument
StringValue некоторых элементов из файлов 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];
Мои вопросы:
Я неправильно открываю файл? Файл поврежден? Я неправильно запрашиваю строковое значение элемента? Как я могу отфильтровать эти символы?
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 в none. Вы можете изменить это для своих собственных целей.
Это только фильтрует содержимое строк атрибутов, откуда пришла моя искаженная строка.