【问题标题】:How to create an API method to read XML data in iPhone?如何创建一个 API 方法来读取 iPhone 中的 XML 数据?
【发布时间】:2011-05-23 06:42:53
【问题描述】:

我正在创建一个基于 XML 的应用程序,我必须在其中从 XML 获取数据并在 iPhone 上显示。我有一个获取数据的 url。但是我不知道如何创建用于 XML 解析的 API 方法。

如何创建 API 方法来确定 url 返回的数据是 XML 格式还是 JSON 格式?

【问题讨论】:

  • 根据 Too Broad 的官方关闭原因:请编辑问题以将其限制为具有足够详细信息的特定问题,以识别适当的答案。

标签: iphone objective-c


【解决方案1】:

查看 Apple 的 XMLPerformance 项目以获取示例代码。

【讨论】:

  • 我知道如何解析 xml,但问题是我没有 xml 文件,我只有 url 可以返回 xml 文件。所以问题是我不知道如何在控制台上检查返回的值由 urland 我没有 xml 元素值,因此我可以开始解析
【解决方案2】:

你必须使用NSXMLParser

【讨论】:

    【解决方案3】:

    您无需创建自定义 API。查看 NSXMLParser 和 libxml2。这还不错,你只需要学会使用它。一旦你看到它应该编写的代码

    【讨论】:

    • NSXMLParser 是最快和最流行的。这应该是因为
    • 我知道如何解析 xml,但问题是我没有 xml 文件,我只有 url 可以返回 xml 文件。所以问题是我不知道如何在控制台上检查返回的值通过网址。
    • 这只是一个想法,但您无法解析 URL 或将其路径保存为字符串,然后解析它返回的任何值
    【解决方案4】:

    关于如何使用 NSXML 解析器 here 有一个很好的教程。 您必须实现解析器委托并从这些委托方法中获取解析值。

    您基本上会对 didStart 和 didEndelements 感兴趣。文档解析结束时调用不同的方法。

    【讨论】:

    • 我知道如何解析 xml,但问题是我没有 xml 文件,我只有 url 可以返回 xml 文件。所以问题是我不知道如何在控制台上检查返回的值通过 url,我没有 xml 元素值,所以我可以开始解析
    【解决方案5】:

    这是我在项目中使用的 xml 解析器代码,它应该允许您解析大多数 XML 文件:

    //
    //  XMLParser.h
    //
    
    #import <Foundation/Foundation.h>
    #import "XMLNode.h"
    
    #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_3_2
    @interface XMLParser : NSObject <NSXMLParserDelegate> {
    #else
    @interface XMLParser : NSObject {
    #endif
        XMLNode *rootElement;
        XMLNode *tempElement;
        NSMutableString *temp;
        NSMutableArray *elements;
    }
    
    - (NSObject *)parseData:(NSData *)data;
    
    // NSXMLParser delegate implementation
    - (void)parserDidStartDocument:(NSXMLParser *)parser;
    - (void)parserDidEndDocument:(NSXMLParser *)parser;
    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict;
    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;
    
    @end
    

    -

    //
    //  XMLParser.m
    //
    
    #import "XMLParser.h"
    
    
    @implementation XMLParser
    
    - (NSObject *)parseData:(NSData *)data
    {
        NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
        [parser setDelegate:self];
        [parser setShouldResolveExternalEntities:YES];
    
        if (![parser parse]) {
            if ([[parser parserError] code] == NSXMLParserUnknownEncodingError) {
                // If encoding is "us-ascii" replace encoding with something known (as NSXMLParser is not supporting this encoding)
                NSString *oldString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
                NSString *newEncodingString = [oldString stringByReplacingOccurrencesOfString:@"encoding=\"us-ascii\"" withString:@"encoding=\"iso-8859-1\"" options:0 range:NSMakeRange(0,100)];
                newEncodingString = [newEncodingString stringByReplacingOccurrencesOfString:@"encoding=\"windows-1251\"" withString:@"encoding=\"iso-8859-1\"" options:0 range:NSMakeRange(0,100)];
    
                [oldString release];
                NSData *nameData = [newEncodingString dataUsingEncoding:NSASCIIStringEncoding];
                NSXMLParser *parser2 = [[NSXMLParser alloc] initWithData:nameData];
                [parser2 setDelegate:self];
                [parser2 setShouldResolveExternalEntities:YES];
                if (![parser2 parse]) {
                    DLog(@"parseXML error : %@",[[parser2 parserError] localizedDescription]);
                }
                [parser2 release];
    
            } else {
                DLog(@"parseXML error : %@",[[parser parserError] localizedDescription]);
            }
    
        }
        [parser release];
    
        return rootElement;
    }
    
    
    - (void)dealloc
    {
        if (tempElement != nil) {
            [tempElement release];
        } 
        if (rootElement != nil) {
            [rootElement release];
        }
        if (temp != nil) {
            [temp release];
        }
        if (elements != nil) {
            [elements release];
        }
    
        [super dealloc];
    }
    
    
    // NSXMLParser delegate implementation
    
    
    - (void)parserDidStartDocument:(NSXMLParser *)parser
    {
        if (elements != nil) {
            [elements release];
        }
        elements = [[NSMutableArray alloc] init];
        if (tempElement != nil) {
            [tempElement release];
            tempElement = nil;
        }
        if (temp != nil) {
            [temp release];
            temp = nil;
        }
        if (rootElement != nil) {
            [rootElement release];
            rootElement = nil;
        }
    }
    
    
    - (void)parserDidEndDocument:(NSXMLParser *)parser
    {
       if (elements != nil) {
            [elements release];
            elements = nil;
        }
        if (tempElement != nil) {
            [tempElement release];
            tempElement = nil;
        }
        if (temp != nil) {
            [temp release];
            temp = nil;
        }
    }
    
    
    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
      namespaceURI:(NSString *)namespaceURI
     qualifiedName:(NSString *)qualifiedName
        attributes:(NSDictionary *)attributeDict
    {
        XMLNode *element = [[[XMLNode alloc] initWithName:elementName] autorelease];
        [element setAttributes:attributeDict];
        if (tempElement != nil) {
            [tempElement addChild:element];
            [elements addObject:tempElement];
            [tempElement release];
        } else {
            rootElement = [element retain];
        }
    
        tempElement = [element retain];
        if (temp != nil) {
            [temp release];
        }
        temp = [[NSMutableString alloc] init];
    }
    
    
    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
      namespaceURI:(NSString *)namespaceURI
     qualifiedName:(NSString *)qName
    {
        [tempElement setContent:temp];
        [temp release];
        temp = nil;
        [tempElement release];
        tempElement = nil;
        if ([elements count] > 0) {
            tempElement = [[elements lastObject] retain];
            [elements removeLastObject];
        }
    }
    
    
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
    {
        if (temp != nil) {
            [temp appendString:string];
        }
    }
    
    @end
    

    -

    //
    //  XMLNode.h
    //
    
    #import <Foundation/Foundation.h>
    
    /**
     * XMLNode represents an XML data node.
     *
     * Every node can contain multiple childs, attributes, a content string
     * and an element name. An XML document is represented using a reference
     * to the document root node.
     * @ingroup Webservice
     */
    @interface XMLNode : NSObject {
    
        NSMutableArray *childs;
        NSDictionary *attributes;
        NSString *content;
        NSString *elementName;
    
    }
    
    /**
     * Return an initialized XMLNode.
     * @param name The element name of the node.
     */
    - (id)initWithName:(NSString *)name;
    
    /**
     * Set the node attributes.
     * @param dictionary A dictionary containing the attributes.
     */
    - (void)setAttributes:(NSDictionary *)dictionary;
    
    /**
     * Set the content as string.
     * @param string The content as string.
     */
    - (void)setContent:(NSString *)string;
    
    /**
     * Add a child node.
     * @param xmlElement The child node.
     */
    - (void)addChild:(XMLNode *)xmlElement;
    
    /**
     * Return a specific attribute.
     * @param name The attribute name.
     * @return The attribute for the specified name or nil.
     */
    - (NSString *)attributeForName:(NSString *)name;
    
    /**
     * Return a child at a specific index.
     * 
     * If the index is out of the bounds, an NSRangeException is thrown.
     * @param index The position of the child (by document order).
     * @return The child at index
     * @see childElementsCount
     */
    - (XMLNode *)childElementAtIndex:(int)index;
    
    /**
     * Return a child with a certain name.
     * @param name The name of the element.
     * @return The element or nil if not available.
     */
    - (XMLNode *)childWithName:(NSString *)name;
    - (XMLNode *)childWithName:(NSString *)name atIndex:(NSInteger)index;
    
    /** 
     * Return the number of child nodes.
     * @return The number of child nodes.
     */
    - (int)childElementsCount;
    - (int)childWithNameElementsCount:(NSString *)name;
    
    /** 
     * Return the node content.
     * @return The node content as string.
     */
    - (NSString *)content;
    
    /**
     * Get the name of the xml element.
     * @return The name of the element.
     */
    - (NSString *)name;
    
    - (void)dealloc;
    
    @end
    

    -

    //
    //  XMLNode.m
    //
    
    #import "XMLNode.h"
    
    
    @implementation XMLNode
    - (id)initWithName:(NSString *)name
    {
        self = [super init];
        elementName = [name copy];
        childs = [[NSMutableArray alloc] init];
        return self;
    }
    
    
    - (void)setAttributes:(NSDictionary *)dictionary
    {
        if (attributes != nil) {
            [attributes release];
        }
        attributes = [dictionary retain];
    }
    
    
    - (void)setContent:(NSString *)string
    {
        if (content != nil) {
            [content release];
        }
        content = [string retain];
    }
    
    - (void)addChild:(XMLNode *)xmlElement
    {
        [childs addObject:xmlElement];
    }
    
    
    - (NSString *)attributeForName:(NSString *)name
    {
        return [attributes objectForKey:name];
    }
    
    
    - (XMLNode *)childElementAtIndex:(int)index
    {
        return [childs objectAtIndex:index];
    }
    
    
    - (XMLNode *)childWithName:(NSString *)name
    {
        int i;
        for (i=0; i<[childs count]; ++i) {
            XMLNode *child = [childs objectAtIndex:i];
            if ([[[child name] lowercaseString] isEqualToString:[name lowercaseString]]) {
                return child;
            }
        }
    
        return nil;
    }
    
    - (XMLNode *)childWithName:(NSString *)name atIndex:(NSInteger)index
    {
        int i;
        int count = 0;
        for (i=0; i<[childs count]; ++i) {
            XMLNode *child = [childs objectAtIndex:i];
            if ([[[child name] lowercaseString] isEqualToString:[name lowercaseString]]) {
                if (count == index)
                    return child;
                count ++;
            }
        }
    
        return nil;
    }
    
    - (int)childElementsCount
    {
        return [childs count];
    }
    
    - (int)childWithNameElementsCount:(NSString *)name
    {
        int i;
        int count = 0;
        for (i=0; i<[childs count]; ++i) {
            XMLNode *child = [childs objectAtIndex:i];
            if ([[[child name] lowercaseString] isEqualToString:[name lowercaseString]]) {
                count ++;
            }
        }
    
        return count;
    }
    
    
    - (NSString *)content
    {
        return content;
    }
    
    
    - (NSString *)name
    {
        return elementName;
    }
    
    
    - (void)dealloc
    {
        if (content != nil) {
            [content release];
        }
        if (childs != nil) {
            [childs release];
        }
        if (attributes != nil) {
            [attributes release];
        }
    
        [super dealloc];
    }
    
    @end
    

    如下使用(此示例用于分析 rss 提要:

    XMLParser *parser = [[XMLParser alloc] init];
    NSObject *rss = [parser parseData:rssFeed];
    feedItems = [(XMLNode *)rss childWithName:@"channel"];
    if (feedItems) {
        NSLog(@"%@",[[feedItems childWithName:@"title"] content]);
    }
    [parser release];
    

    如果您需要更复杂的分析,请查看 XMLNode.h 以获取更多方法

    【讨论】:

      【解决方案6】:

      听起来您的问题不是如何解析 XML,而是如何将 XML 文档从 Web 下载到 NSData 对象等中。

      您可以使用开源的ASIHTTPRequest 框架快速下载您的XML 数据。看看how-to document on setting up an asynchronous request。

      假设 URL 正确且请求成功,则 XML 数据将存储在请求的 responseData 属性中。

      然后您可以使用各种方法来解析此属性中的 XML 数据。我推荐libxml2,因为它是最快的。但此时您可以使用任何您想要的解析器引擎和方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-10
        • 2021-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多