如何创建一个API方法来读取iPhone中的XML数据?

发布于 2024-11-09 06:43:40 字数 143 浏览 1 评论 0原文

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

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

I am creating an XML based application in which I have to fetch data from XML and show on iPhone. I have a url through which the data is being fetched. But I don't know how to create the API method for XML parsing.

How can I create an API method for determining the data returned by the url is in XML format or in JSON format?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

不知所踪 2024-11-16 06:43:40

请参阅 Apple 的 XMLPerformance 项目以获取示例代码。

Look at Apple's XMLPerformance project for sample code.

云淡月浅 2024-11-16 06:43:40

您必须使用 NSXMLParser

You have to use the NSXMLParser

恍梦境° 2024-11-16 06:43:40

您不需要创建自定义 API。查看 NSXMLParser 和 libxml2。这方面并不差,你只需要学会使用它即可。一旦你看到代码,它应该从

You don't need to create a custom API. Check out NSXMLParser, and libxml2. Is not bad at this you just have to learn to use it. Once you see the code it should make since

扛刀软妹 2024-11-16 06:43:40

有一个关于如何使用 NSXML 解析器的很好的教程

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

There is a nice tutorial on how you can use the NSXML parser here.
You have to implement the parser delegate and get the parsed values from those delegate methods.

You would be basically interested in didStart and didEndelements. A different method is called when the document parsing is over.

夜声 2024-11-16 06:43:40

这是我在项目中使用的 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 feed:

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需要更复杂的分析

Here is the xml parser code I'm using in my projects, it should allow you to parse most XML files :

//
//  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

use this as following (this sample is to analyze a rss feed :

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

Check XMLNode.h for more methods if you need a more complex analysis

山田美奈子 2024-11-16 06:43:40

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

您可以使用开源的ASIHTTPRequest框架快速下载您的XML数据。查看有关设置异步请求的操作文档

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

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

It sounds like your question is not how to parse XML, but how to download an XML document from the web into an NSData object, or the like.

You can use the open source ASIHTTPRequest framework to quickly download your XML data. Take a look at the how-to document on setting up an asynchronous request.

Assuming the URL is correct and the request is successful, the XML data will be stored in the request's responseData property.

You can then use various methods for parsing the XML data in this property. I recommend libxml2, as it is the fastest. But you could use whatever parser engine and method you want, at this point.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文