Как NSXMLParser различает разные элементы?

Я только что сделал учебник по NSXMLParser. То, что я полностью в недоумении, это то, как NSXMLParser различает различные элементы. Мне это кажется неопределенным.

Это мой XML

<?xml version="1.0" encoding="UTF-8"?>
<Prices>
<Price id="1">
<name>Rosie O'Gradas</name>
<Beer>4.50</Beer>
<Cider>4.50</Cider>
<Guinness>4</Guinness>
</Price>
</Prices>

А это мой парсер

-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if ([elementName isEqualToString:@"Prices"]) {
    app.listArray = [[NSMutableArray alloc] init];
    NSLog(@"The Prices Count");
}
else if ([elementName isEqualToString:@"Price"]) {
    thelist = [[List alloc] init];
    thelist.drinkID = [[attributeDict objectForKey:@"id"]integerValue];
}
}

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

} else {
    [currentElementValue appendString:string];
}

 }

-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:@"Prices"]) {
    return;
}
if ([elementName isEqualToString:@"Price"]) {
    [app.listArray addObject:thelist];
    thelist = nil;

} else {
    [thelist setValue:currentElementValue forKey:elementName];
    currentElementValue = nil;
}
 }

Я заметил, что имена свойств в объекте данных были такими же, как в парсере. Так что я понял это по крайней мере.

То, что я в недоумении, это то, где он присваивает этим свойствам их значение.

Таким образом, в начале он инициализирует объект данных с

      thelist = [[List alloc] init];

(List - это объект Data) Но потом он делает первое, что я не понимаю

     thelist.drinkID = [[attributeDict objectForKey:@"id"]integerValue];

Потому что он в операторе if не перезаписывается каждый раз, когда находит атрибут id. Или объявление theList создает несколько объектов?

В найденных персонажах я действительно понятия не имею, что происходит. Насколько я могу судить, строка foundCharaters - это каждый бит текста внутри элементов. Таким образом, текущее значение элемента - это просто набор строк, добавленных вместе (но я не могу сказать, потому что по какой-то причине я не могу это сделать).

Оттуда в разделе didEndElement мне интересно, если это правильная интерпретация кода.

    if ([elementName isEqualToString:@"Price"]) {
    [app.listArray addObject:thelist];
    thelist = nil;
    }

Я понимаю, что каждый раз, когда синтаксический анализатор попадает в элемент Price, объект массива app.list (объявленный в другом классе) добавляет объект "список".

Но здесь есть момент, когда мое непонимание в более раннем методе вступает в силу

else {
    [thelist setValue:currentElementValue forKey:elementName];
    currentElementValue = nil;
}

Что они здесь делают? Из того, что я вижу, текущим значением элемента является просто набор символов из файла XML. Как это организовано? С именем элемента?

Еще один вопрос (извините за длину), почему имя элемента не чувствительно к регистру, я экспериментировал и обнаружил, что это не так. Оба языка чувствительны к регистру.

1 ответ

Если я правильно истолковываю ваш вопрос, речь идет о понимании кода, который работает нормально.

В вашем XML у вас есть 4 дочерних элемента для Price с id=1: name, Beer, Cider а также Guinness,

foundCharacters Метод найдет символы внутри этих 4 тегов XML, то есть то, что написано между <name> а также </name>, <Beer> а также </Beer>и т. д. В вашем случае это строка Rosie O'Gradas за nameзатем строка 4.50 за Beer и т.п.

Когда символы найдены, метод сначала проверяет, существует ли строка контейнера, если нет, то создает ее как currentElementValue, Если он существует, он добавляет найденные символы.

Что происходит дальше, по логике? Это ударит didEndElement метод, в первом случае тег </name>, В этом случае он назначит собранный текст в currentElementValue к ключу @"name" и поместите эту пару ключ-значение в список. Список имеет тип List, который определяется где-то еще, но, по-видимому, это по существу NSDictionary,

Так как currentElementValue был успешно сохранен, он должен быть уничтожен, поэтому проверка его существования при следующем обращении foundCharacters буду работать.

Очистить?

Другие вопросы по тегам