Попытка удалить пробелы не работает в методе NSXMLparser foundCharacters - PullRequest
1 голос
/ 14 сентября 2009

Я анализирую xml-файл и пытаюсь удалить пробельные символы в моем currentElementValue, потому что он испортил пару вещей.

В окне вывода я вижу, что есть пара возвратов каретки и вкладок

(gdb) po string
Keep the arms on the side, and lift your leg.
(gdb) po currentElementValue



        Keep the arms on the side, and lift your leg.
(gdb) 

Это моя функция foundCharacters, и я, к сожалению, пытаюсь использовать stringByTrimmingCharactersInSet, но безуспешно.

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
    if(!currentElementValue) 
        currentElementValue = [[NSMutableString alloc] initWithString:string];
    else
    {       

        [currentElementValue appendString:string];

        currentElementValue = [currentElementValue stringByTrimmingCharactersInSet:
                               [NSCharacterSet newlineCharacterSet]];       
            NSString *instructions = @"instructions";   
        [directions setValue:string forKey:instructions];  //mm 
        [appDelegate.directions setValue:string forKey:instructions];
        //[appDelegate.directions setObject:string forKey:currentElementValue];
    //  [appDelegate
    }
}

Я получаю эту ошибку *** Завершение работы приложения из-за неперехваченного исключения «NSInvalidArgumentException», причина: «Попытка изменить неизменяемый объект с appendString:» Что странно, так как мой currentElementValue является NSMutableString .. Так что же не так? У кого-нибудь есть подсказка или идея?

Ответы [ 4 ]

7 голосов
/ 14 сентября 2009

Давайте пройдемся по этому пути, найдем вашу ошибку и решим проблему утечки памяти:

Сначала вы создаете NSMutableString. Отлично. (+1 сохранить счет)

Затем вы добавляете еще одну строку в NSMutableString. Все в порядке. (все еще +1 сохраняют счет).

Затем вы обрезаете newlineCharacterSet, который возвращает ... автоматически выпущенную строку NSString. Поскольку этот объект отличается от вашего исходного объекта, вы вытекли из исходного объекта (так как он имел счет сохранения +1 и у вас больше нет указателя на него), и теперь у вас есть неизменяемая строка NSS для загрузки. Это означает, что в следующий раз, когда этот метод будет вызван, вы попытаетесь добавить строку в строку NSString, которая вызовет исключение «не может изменить неизменяемый объект».

Вот быстрый способ решить эту проблему:

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
    if(!currentElementValue) 
        currentElementValue = [[NSMutableString alloc] initWithString:string];
    else
    {           

        [currentElementValue appendString:string];

        NSString *trimmedString = [currentElementValue stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
        [currentElementValue setString:trimmedString];

        NSString *instructions = @"instructions";       
        [directions setValue:string forKey:instructions];  //mm 
        [appDelegate.directions setValue:string forKey:instructions];
        //[appDelegate.directions setObject:string forKey:currentElementValue];
    //  [appDelegate
    }
}

(сохранить обрезанную строку в другой переменной, затем использовать setString: метод NSMutableString для передачи содержимого, но без потери указателя на NSMutableString)

0 голосов
/ 28 июня 2011
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{ 
  //  Removing whitspace and newline characters
  string   =   [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

  //  If no characters are left return
  if([string length] == 0) return;

  //Rest of the code for saving the string
0 голосов
/ 21 ноября 2009

Я нашел чистый способ работы с текстом узла. Предполагается, что вы владеете содержимым / форматом XML. Сейчас я использую раздел CDATA для атрибута text () моего узла. Сюда не входят пробелы, которые я использовал бы для составления таблицы в своем XML-документе.

Код для чтения выглядит так:

- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock {
NSLog(@"%s", __FUNCTION__);
NSLog(@"[%@]", CDATABlock);

NSString *strData = [[NSString alloc] initWithData:CDATABlock encoding: NSUTF8StringEncoding ];

NSLog(@"convertToString=[%@]", strData);

}

и фрагмент XML выглядит следующим образом (учебник с «известными цитатами»):

<quote><![CDATA[And in the end...in your years.]]></quote>

и вывод трассировки будет таким:

2009-11-21 13:17:51.901 Fate[2241:4203] -[XMLReader parser:foundCDATA:]
2009-11-21 13:17:51.901 Fate[2241:4203] [<416e6420 696e2074 68652065 6e642c20 69742773 206e6f74 20746865 20796561 72732069 6e20796f 7572206c 69666520 74686174 20636f75 6e742e20 20497427 73207468 65206c69 66652069 6e20796f 75722079 65617273 2e>]
2009-11-21 13:17:55.774 Fate[2241:4203] convertToString=[And in the end, it's not the years in your life that count.  It's the life in your years.]]>
0 голосов
/ 14 октября 2009

Между прочим ... Я подумал, что NSXMLParser должен предоставить настройки для обработки пробелов, то есть "сохранять пробелы" в спецификации W3.org для XML / XSLT - кроме того, мне не нравится получать набор символов прямо для чего-то вроде отделки. По сути, я хотел получить доступ к "@text ()", как при преобразовании XML / XMSLT. Итак, я немного покопался и нашел этот метод. Обратите внимание, что можно добавить строку пробела к накопленному тексту. С первой попытки это не работает, но мне нужно больше экспериментировать и дважды проверять мой синтаксис (то есть навыки «вырезать и вставить»:))

- (void)parser:(NSXMLParser *)parser foundIgnorableWhitespace:(NSString *)whitespaceString

Параметры: парсер Объект парсера.

whitespaceString Строка, представляющая все или часть игнорируемых пробельных символов текущего элемента.

Обсуждение Все пробельные символы элемента (включая возврат каретки, символы табуляции и символы новой строки) не могут быть предоставлены посредством отдельного вызова этого метода. Анализатор может отправить делегату несколько синтаксических анализаторов: foundIgnorableWhitespace: сообщения, чтобы сообщить о пробельных символах элемента. Вы должны добавлять символы в каждом вызове к текущему накоплению символов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...