0

这是第一次使用 NSXMLParser 并且想知道您是否给我一些从 http 请求解析返回的 xml 的方向,如下所示:

<?xml version="1.0" ?>
<theresponse>
 <status>OK</status>
 <pricing currency="USD" symbol="$">
   <price class="items">24.00</price>
   <price class="shipping">6.00</price>
   <price class="tax">1.57</price>
 </pricing>
</theresponse>

我知道解析委托方法的基础知识,我只想知道在 didEndElement/foundCharacters/didStartElement 中用于检索上述项目(货币/项目/运费/税)的代码是什么样的?非常感谢任何帮助。

4

2 回答 2

1

这比一些标准NSXMLParser代码要复杂一些;因为本质上,当您在寻找shipping“您想要的”时6.00,但这两条数据会以不同的委托方法返回给您,这是正常的。但是通常元素会被命名为“ shipping”,因此在parser:didEndElement:namespaceURI:qualifiedName:将元素名称传递给方法时,您会自动获得该元素名称。

解决方案看起来很简单,有一个_currentAttributesivar 并parser:didStartElement:namespaceURI:qualifiedName:attributes:做类似的事情_currentAttributes = attributeDict;,然后在didEndElement:方法中处理它。然而这种风格很容易被打破,即使在这个适度简单的XML.

我的处理方式是存储传入的属性字典didStartElement:,并将其设置在字典中作为元素名称键的对象。将这种风格与NSMutableString作为 characterBuffer 的标准使用相结合,您可以将所有逻辑放入didEndElement:方法中。

旁注:我也很喜欢让我的NSXMLParserDelegateNSXMLParser子类,就像这个一样。但是,如果不是,委托方法将是相同的。

项目解析器.h

#import <Foundation/Foundation.h>
@interface ItemParser : NSXMLParser <NSXMLParserDelegate>
@property (readonly) NSDictionary *itemData;
@end

项目解析器.m

#import "ItemParser.h"
@implementation ItemParser {
    NSMutableDictionary *_itemData;
    NSMutableDictionary *_attributesByElement;
    NSMutableString *_elementString;
}
-(NSDictionary *)itemData{
    return [_itemData copy];
}
-(void)parserDidStartDocument:(NSXMLParser *)parser{
    _itemData = [[NSMutableDictionary alloc] init];
    _attributesByElement = [[NSMutableDictionary alloc] init];
    _elementString = [[NSMutableString alloc] init];
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
    // Save the attributes for later.
    if (attributeDict) [_attributesByElement setObject:attributeDict forKey:elementName];
    // Make sure the elementString is blank and ready to find characters
    [_elementString setString:@""];
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
    // Save foundCharacters for later
    [_elementString appendString:string];
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
    if ([elementName isEqualToString:@"status"]){
        // Element status only contains a string i.e. "OK"
        // Simply set a copy of the element value string in the itemData dictionary
        [_itemData setObject:[_elementString copy] forKey:elementName];
    } else if ([elementName isEqualToString:@"pricing"]) {
        // Pricing has an interesting attributes dictionary 
        // So copy the entries to the item data
        NSDictionary *attributes = [_attributesByElement objectForKey:@"pricing"];
        [_itemData addEntriesFromDictionary:attributes];
    } else if ([elementName isEqualToString:@"price"]) {
        // The element price occurs multiple times.
        // The meaningful designation occurs in the "class" attribute.
        NSString *class = [[_attributesByElement objectForKey:elementName] objectForKey:@"class"];
        if (class) [_itemData setObject:[_elementString copy] forKey:class];
    }
    [_attributesByElement removeObjectForKey:elementName];
    [_elementString setString:@""];
}
-(void)parserDidEndDocument:(NSXMLParser *)parser{
    _attributesByElement = nil;
    _elementString = nil;
}
-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
    NSLog(@"%@ with error %@",NSStringFromSelector(_cmd),parseError.localizedDescription);
}
-(BOOL)parse{
    self.delegate = self;
    return [super parse];
}
@end

因此,为了测试,我将XML您在上面发布的内容存储到一个名为“ItemXML.xml”的文件中。并使用以下代码对其进行了测试:

NSURL *url = [[NSBundle mainBundle] URLForResource:@"ItemXML" withExtension:@"xml"];
ItemParser *parser = [[ItemParser alloc] initWithContentsOfURL:url];
[parser parse];
NSLog(@"%@",parser.itemData);

我得到的结果是:

{
    currency = USD;
    items = "24.00";
    shipping = "6.00";
    status = OK;
    symbol = "$";
    tax = "1.57";
}
于 2012-04-08T18:55:19.370 回答
0

看看这个教程。它解释了如何使用 NSXMLParser 将 XML 中的数据解析为您自己的数据格式。

于 2012-04-06T19:02:24.693 回答