Лучший подход для синтаксического анализа XML на iPhone
Я ознакомился с NSXMLParser с iPhone SDK, но я нахожу, что это обусловлено событиями, что это неудобно для моих целей. Я просто хочу извлечь некоторые значения элементов, но эта концепция работы с startElement, foundCharacters и endElement кажется большей работой, чем это действительно должно быть. Я просто смотрю на это не так, или есть более простой способ работы с XML в iPhone SDK на основе дерева / DOM?
Если совет состоит в том, чтобы просто работать с NSXMLParser, есть ли определенные шаблоны проектирования, которые я могу использовать, чтобы мой код не имел 5 уровней вложенных ifs в методе startElement?
- Собственное использование приложения делегата приложения iPhone
- К ARC или не к ARC? Каковы плюсы и минусы?
- Как передать объект с помощью NSNotificationCenter
- Сколько стоит разработка приложения для iPhone?
- Статическая строковая переменная в Objective C на iphone
- Подчеркивать префикс имени свойства?
- Как распознать салфетки во всех четырех направлениях?
- фильтрация NSArray в новый NSArray в объективе-c
- iTunes Connect API
- Вам нужно создать NSAutoreleasePool в блоке в GCD?
- Округлые углы на UIImage
- Как сделать ImageView UITableViewCell фиксированным, даже когда изображение меньше
- Как заставить приложение запускать NSTimer в фоновом режиме?
Если вы находитесь на iPhone, использование синтаксического анализа на основе дерева может быть непомерно богатым. Поверьте мне, я был там, и я пробовал много разных подходов за последние пять месяцев разработки моего основного приложения для iPhone. Разбор на основе дерева работает отлично, пока вы не загрузите stream комментариев пользователя, содержащий 400 очень длинных комментариев, синхронизируя около 600 КБ необработанных данных. В стороне от размера результирующего дерева XML память, выделенная внутренне при создании этого дерева, может быть огромной.
Я закончил создание варианта NSXMLParser, который извлекает данные из поставляемого NSInputStream, а не использует один кусок данных и который пропускает только 1 Кбайт за раз в libxml для обработки (NSXMLParser также использует libxml, но передает 100% данных за один присест).
Исходный код доступен в github (смотрите в папке StreamingXMLParser). Вы также найдете там суперменс делегата; для большинства потребностей синтаксического анализа вы можете подclassифицировать AQXMLParserDelegate и реализовать -start[Element]WithAttributes: (NSDictionary *) attrs
и -end[Element]
в вашем подclassе. Эти методы будут вызваны для вас, когда будут открыты tags начала и конца, а внутри конечного тега вы можете использовать self.characters
для доступа к символам содержимого или CDATA элемента.
Для получения дополнительной информации о относительной памяти следы разных парсеров (хотя и на Mac, а не на iPhone) см. Здесь мой оригинальный пост в блоге и последующее описание на NSXMLDocument.
Рассмотрим следующий fragment кода, который использует libxml2 , обертки libxml2 от Matt Gallagher и ASIHTTPRequest от Ben Copsey для анализа XML-документа.
Экземпляр экземпляра типа NSArray*
будет содержать объекты NSDictionary*
которые вы можете проанализировать рекурсивно, чтобы получить NSDictionary*
данные.
Или, если вы знаете схему своего XML-документа, вы можете написать запрос XPath , чтобы nodeContent
nodeAttribute
значение nodeContent
или nodeAttribute
.
ASIHTTPRequest *request = [ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://stackoverflow.com/"]; [request start]; NSError *error = [request error]; if (!error) { NSData *response = [request responseData]; NSLog(@"Root node: %@", [[self query:@"//" withResponse:response] description]); } else @throw [NSException exceptionWithName:@"kHTTPRequestFailed" reason:@"Request failed!" userInfo:nil]; [request release]; ... - (id) query:(NSString *)xpathQuery withResponse:(NSData *)respData { NSArray *nodes = PerformXMLXPathQuery(respData, xpathQuery); if (nodes != nil) return nodes; return nil; }
Повторное копирование кода из Seismic XML обеспечивает очень хороший API, который создает подclassы NSObject из XML.
Если совет состоит в том, чтобы просто работать с NSXMLParser, есть ли определенные шаблоны проектирования, которые я могу использовать, чтобы мой код не имел 5 уровней вложенных ifs в методе startElement?
Я зависим от того, что вы пытаетесь сделать. Вы можете поместить свои имена элементов в словарь и принять действие на основе соответствующего объекта в словаре – это действительно то, что делает SeismicXML.