Как 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
буду работать.
Очистить?