Разбор XML в iPhone - PullRequest
       1

Разбор XML в iPhone

3 голосов
/ 10 августа 2011

Я новичок в разборе XML. Я полностью обдумал, сколько методов мы должны требовать для разбора XML и что использует этот метод. Я хочу отправлять ввод в webservied и с помощью разбора XML, я хочу отобразить результат в моем текстовом поле.

Ответы [ 7 ]

5 голосов
/ 10 августа 2011

Информацию о том, как выбрать синтаксический анализатор XML для вашего приложения iOS, см. В следующих вопросах:

Выбор правильного синтаксического анализатора XML IOS

Я выбираю TouchXML для своих проектов,Это DOM-парсер и имеет поддержку XPath:

https://github.com/TouchCode/TouchXML

3 голосов
/ 10 августа 2011

Вы должны использовать следующие методы:

- (void)parseXMLFileAtURL:(NSString *)URL { //own method from me, URL could be local file or internet website 
    itemsOfFeed = [[NSMutableArray alloc] init];
    NSURL *xmlURL = [NSURL URLWithString:URL];
    feedParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
    [feedParser setDelegate:self];
    [feedParser setShouldProcessNamespaces:NO];
    [feedParser setShouldReportNamespacePrefixes:NO];
    [feedParser setShouldResolveExternalEntities:NO];
    [feedParser parse];
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    //in case of an error
}

- (void)parserDidStartDocument:(NSXMLParser *)parser {
    // start to parse xml
}

-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    feedElement = [elementName copy];
    if([elementName isEqualToString:@"item"]) { //main xml tag
        item = [[NSMutableDictionary alloc] init];
        feedTitle = [[NSMutableString alloc] init];
        feedDate = [[NSMutableString alloc] init];
        feedText = [[NSMutableString alloc] init];
        feedLink = [[NSMutableString alloc] init];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if([feedElement isEqualToString:@"title"]) {
        [feedTitle appendString:string];
    } else if([feedElement isEqualToString:@"link"]) { // some examples of tags
        [feedLink appendString:string];
    } else if([feedElement isEqualToString:@"content:encoded"]) {
        [feedText appendString:string];
    } else if([feedElement isEqualToString:@"pubDate"]) {
        [feedDate appendString:string];
    }
}

- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if([elementName isEqualToString:@"item"]) {
        [item setObject:feedTitle forKey:@"title"];
        [item setObject:feedDate forKey:@"date"];
        [item setObject:feedText forKey:@"text"];       
        [item setObject:feedLink forKey:@"link"];
        [itemsOfFeed addObject:item];
    }
}

- (void)parserDidEndDocument:(NSXMLParser *)parser {
    [self.myTableView reloadData]; // for example reload table view
    [self writeArrayToFile]; //or write to a local property list
}

в заголовочном файле:

NSMutableArray *itemsOfFeed;
NSXMLParser *feedParser;
NSMutableDictionary *item;
NSMutableString *feedElement;
NSMutableString *feedTitle, feedDate, feedText, feedLink; //strings of your tags

Тогда у вас есть:

  • NSArray
    • NSDictionary
      • объект a
      • объект b
      • объект c

Justполучите доступ к объекту a и поместите его в текстовое поле

, надеюсь, этот пример кода поможет вам

2 голосов
/ 18 октября 2012

У меня есть демонстрационное приложение для анализа статического XML в UITableView, я думаю, этот наверняка поможет вам.

2 голосов
/ 10 августа 2011

Привет, я бы лично предпочел использовать NSXMLParser.

Напишите свой собственный код, который использует реализацию методов NSXMLParserDelegate.

Но все же есть некоторые сторонние библиотеки. Вот хороший пример для сравнения того, как все эти парсеры отличаются друг от друга, а также хорошее объяснение. Код также доступен там.

Надеюсь, это поможет вам.

-Mrunal

2 голосов
/ 10 августа 2011

Вот очень полезное руководство.

http://www.edumobile.org/iphone/iphone-programming-tutorials/parsing-an-xml-file/

0 голосов
/ 27 марта 2015

Попробуйте это:

XMLReader.h

//
//  XMLReader.h
//
//

#import <Foundation/Foundation.h>

@interface XMLReader : NSObject <NSXMLParserDelegate>
{
    NSMutableArray *dictionaryStack;
    NSMutableString *textInProgress;
    NSError *errorPointer;
}

+ (NSDictionary *)dictionaryForPath:(NSString *)path error:(NSError **)errorPointer;
+ (NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)errorPointer;
+ (NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)errorPointer;

@end

XMLReader.m

//
//  XMLReader.m
//

#import "XMLReader.h"

//NSString *const kXMLReaderTextNodeKey = @"text";

@interface XMLReader (Internal)

- (id)initWithError:(NSError **)error;
- (NSDictionary *)objectWithData:(NSData *)data;

@end

@implementation XMLReader

#pragma mark -
#pragma mark Public methods

+ (NSDictionary *)dictionaryForPath:(NSString *)path error:(NSError **)errorPointer
{
    NSString *fullpath = [[NSBundle bundleForClass:self] pathForResource:path ofType:@"xml"];
    NSData *data = [[NSFileManager defaultManager] contentsAtPath:fullpath];
    NSDictionary *rootDictionary = [XMLReader dictionaryForXMLData:data error:errorPointer];

    return rootDictionary;
}

+ (NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)error
{
    XMLReader *reader = [[XMLReader alloc] initWithError:error];
    NSDictionary *rootDictionary = [reader objectWithData:data];
    [reader release];

    return rootDictionary;
}

+ (NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)error
{
    NSArray* lines = [string componentsSeparatedByString:@"\n"];
    NSMutableString* strData = [NSMutableString stringWithString:@""];

    for (int i = 0; i < [lines count]; i++)
    {
        [strData appendString:[[lines objectAtIndex:i] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
    }

    NSData *data = [strData dataUsingEncoding:NSUTF8StringEncoding];
    return [XMLReader dictionaryForXMLData:data error:error];
}

#pragma mark -
#pragma mark Parsing

- (id)initWithError:(NSError **)error
{
    if ((self = [super init]))
    {
        errorPointer = *error;
    }

    return self;
}

- (void)dealloc
{
    [dictionaryStack release];
    [textInProgress release];

    [super dealloc];
}

- (NSDictionary *)objectWithData:(NSData *)data
{
    // Clear out any old data
    [dictionaryStack release];
    [textInProgress release];

    dictionaryStack = [[NSMutableArray alloc] init];
    textInProgress = [[NSMutableString alloc] init];

    // Initialize the stack with a fresh dictionary
    [dictionaryStack addObject:[NSMutableDictionary dictionary]];

    // Parse the XML
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    parser.delegate = self;
    BOOL success = [parser parse];
    [parser release];

    // Return the stack's root dictionary on success
    if (success){
        NSDictionary *resultDict = [dictionaryStack objectAtIndex:0];
        return resultDict;
    }

    return nil;
}

# pragma mark
# pragma mark - NSXMLParserDelegate methods

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    // Get the dictionary for the current level in the stack
    NSMutableDictionary *parentDict = [dictionaryStack lastObject];

    // Create the child dictionary for the new element
    NSMutableDictionary *childDict = [NSMutableDictionary dictionary];

    // Initialize child dictionary with the attributes, prefixed with '@'
    for (NSString *key in attributeDict) {
        [childDict setValue:[attributeDict objectForKey:key]
                     forKey:key];
    }

    // If there's already an item for this key, it means we need to create an array
    id existingValue = [parentDict objectForKey:elementName];

    if (existingValue){
        NSMutableArray *array = nil;

        if ([existingValue isKindOfClass:[NSMutableArray class]]){
            // The array exists, so use it
            array = (NSMutableArray *) existingValue;
        }
        else{
            // Create an array if it doesn't exist
            array = [NSMutableArray array];
            [array addObject:existingValue];

            // Replace the child dictionary with an array of children dictionaries
            [parentDict setObject:array forKey:elementName];
        }

        // Add the new child dictionary to the array
        [array addObject:childDict];
    }
    else{
        // No existing value, so update the dictionary
        [parentDict setObject:childDict forKey:elementName];
    }

    // Update the stack
    [dictionaryStack addObject:childDict];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    // Update the parent dict with text info
    NSMutableDictionary *dictInProgress = [dictionaryStack lastObject];

    // Pop the current dict
    [dictionaryStack removeLastObject];

    // Set the text property
    if ([textInProgress length] > 0){
        if ([dictInProgress count] > 0){
            [dictInProgress setObject:textInProgress forKey:kXMLReaderTextNodeKey];
        }
        else{
            // Given that there will only ever be a single value in this dictionary, let's replace the dictionary with a simple string.
            NSMutableDictionary *parentDict = [dictionaryStack lastObject];
            id parentObject = [parentDict objectForKey:elementName];

            // Parent is an Array
            if ([parentObject isKindOfClass:[NSArray class]]){
                [parentObject removeLastObject];
                [parentObject addObject:textInProgress];
            }

            // Parent is a Dictionary
            else{
                [parentDict removeObjectForKey:elementName];
                [parentDict setObject:textInProgress forKey:elementName];
            }
        }

        // Reset the text
        [textInProgress release];
        textInProgress = [[NSMutableString alloc] init];
    }

    // If there was no value for the tag, and no attribute, then remove it from the dictionary.
    else if ([dictInProgress count] == 0){
        NSMutableDictionary *parentDict = [dictionaryStack lastObject];
        [parentDict removeObjectForKey:elementName];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    // Build the text value
    [textInProgress appendString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
    // Set the error pointer to the parser's error object
    if (errorPointer)
        errorPointer = parseError;
}

@end

Используйте это:

NSMutableDictionary *yourDic= (NSMutableDictionary *)[XMLReader dictionaryForXMLData:yourData error:&error];
0 голосов
/ 31 октября 2012

Доступные сторонние библиотеки, доступные ниже, зависят от выбора разработчика, что лучше?

  • NSXMLParser
  • libxml2
  • TBXMLParser
  • TouchXMLParser
  • KissXMLParser
  • TinyXMLParser
  • GDataXMLParser

И вы также можете получить больше информации по этой замечательной учебной ссылке http://www.raywenderlich.com/553/how-to-chose-the-best-xml-parser-for-your-iphone-project

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