开发者

most efficent way to parse XML With NSXMLParser

开发者 https://www.devze.com 2023-04-12 16:04 出处:网络
I am trying to figure out the best approach to parsing large datasets of xml with the xmlparser delegate.. (basically what the heck do i put the data into?)

I am trying to figure out the best approach to parsing large datasets of xml with the xmlparser delegate.. (basically what the heck do i put the data into?)

the xml data will look like this.

<Rows>
<Row ID="76" MANF="JARD" ISMANUF="F" ISSER="F"/>
<Row ID="38" MANF ="SANBIN" ISMANUF ="F" ISSER ="T"/>
<Rows>

I am looking for a high level responses so I can go away and do more research as their is obviously several different ways of going about this.. I would like to know the best/most efficient to store the data coming back from NSXMLParser and also would like something tha开发者_开发技巧t I will have the ability to cache...

Thus far I have been looking at NSMutabledictionarys however have heard this might not be sutible so I have now started to look at creating my own object.. but the data coming back from my parsing delegate is only compatible with strings.. so if i have a bool value I cannot put it into my object.. any help would be greatly appreciated as I am at a bit of a loss.


I've implemented an efficient enough XML-to-NSDictionary parser. You can return it as an NSMutableDictionary if you want to. I don't currently have a github or anything up, so I'll post the code inline here. It makes use of the TBXML XML parsing library (no XPath support, and read-only parsing, but fairly efficient and high-level).

EDIT: I just realised, my parser was made to parse element names and text inside the elements, but not element attributes, which is how your XML dataset is laid out. Unfortunately, the below code won't parse the attributes. You've got a starting point though, you can change the code which uses ->firstChild and ->nextSibling to read attributes.


XML.h

@interface XML : NSObject

/**
 * Constructs an NSDictionary from the provided XML tree.
 *
 * Uses the default prefix of 'config'.
 */
+ (NSDictionary *)dictionaryForXMLTree:(TBXMLElement *)tree;

/**
 * Constructs an NSDictionary from the provided XML tree.
 *
 * The format of the dictionary keys is:
 * section/[subsection/.../]optionName
 */
+ (NSDictionary *)dictionaryForXMLTree:(TBXMLElement *)tree
                            withPrefix:(NSString *)keyPrefix;

/**
 * Iteratively parses configuration areas from the provided XML document.
 *
 * If an 'list' area is encountered, its immediate children are added to
 * the dictionary as a numbered list (i.e list/1/..., list/2/...).
 */
+ (NSDictionary *)dictionaryFromXML:(TBXML *)xmlDoc;

@end

XML.m

NSString *stripHTML(const char* xmlString);

NSString* stripHTML(const char* xmlString)
{
    return [[[NSString stringWithUTF8String:xmlString]
      stringByReplacingOccurrencesOfString:@"&amp;"
      withString:@"&"]
     stringByReplacingOccurrencesOfString:@"&#13;"
            withString:@""];
}

@implementation XML

@synthesize configDict;

#pragma mark - XML parsing

+ (NSDictionary *)itemisedDictionaryForXMLTree:(TBXMLElement *)tree
                                    withPrefix:(NSString *)keyPrefix
{
    NSMutableDictionary *returnValues =
    [[NSMutableDictionary alloc] init];
    NSUInteger itemNumber = 1;
    for (TBXMLElement *option = tree->firstChild;
         option != nil;
         option = option->nextSibling)
    {
        if(option->text == NULL)
            option->text = "";

        NSString *childPrefix = [NSString stringWithFormat:@"%@/%u",
                                 keyPrefix, itemNumber++];
        [returnValues setObject:stripHTML(option->text)
                         forKey:childPrefix];

        [returnValues addEntriesFromDictionary:
         [self dictionaryForXMLTree:option withPrefix:childPrefix]];
    }

    return [returnValues autorelease];
}

+ (NSDictionary *)dictionaryForXMLTree:(TBXMLElement *)tree
                            withPrefix:(NSString *)keyPrefix
{
    NSMutableDictionary *returnValues =
    [[NSMutableDictionary alloc] init];
    for (TBXMLElement *option = tree->firstChild;
         option != nil;
         option = option->nextSibling)
    {        
        if(option->text == NULL)
            option->text = "";

        NSString *childPrefix = [NSString stringWithFormat:@"%@/%s",
                                 keyPrefix,
                                 option->name];
        [returnValues setObject:stripHTML(option->text)
                         forKey:childPrefix];

        [returnValues addEntriesFromDictionary:
         [self dictionaryForXMLTree:option withPrefix:childPrefix]];
    }

    return [returnValues autorelease];
}

+ (NSDictionary *)dictionaryForXMLTree:(TBXMLElement *)tree
{
    return [self dictionaryForXMLTree:tree withPrefix:@"config"];
}

+ (NSDictionary *)dictionaryFromXML:(TBXML *)xmlDoc
{
    NSMutableDictionary *config = [[NSMutableDictionary alloc] init];
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    TBXMLElement *rootElement = [xmlDoc rootXMLElement];
    if(rootElement != nil)
    {
        for(TBXMLElement *configArea = rootElement->firstChild;
            configArea != nil;
            configArea = configArea->nextSibling)
        {
            NSString *areaName = [NSString stringWithFormat:@"%s",
                                  configArea->name];
            if([areaName
                isEqualToString:@"list"]) // multiple children with the same name
            {
                [config addEntriesFromDictionary:
                 [self itemisedDictionaryForXMLTree:configArea
                                         withPrefix:areaName]];
            } else {
                [config addEntriesFromDictionary:
                 [self dictionaryForXMLTree:configArea
                                 withPrefix:areaName]];
            }
        }
    }

    [pool release];
    return [config autorelease];
}

+ (NSDictionary *)fetchConfig:(NSURL *)atURL
{
    TBXML *xmlDoc = [TBXML tbxmlWithURL:atURL];
    return [XML dictionaryFromXML:xmlDoc];
}

+ (NSDictionary *)parseConfigFromXMLString:(NSString *)xmlString
{
    TBXML *xmlDoc = [TBXML tbxmlWithXMLString:xmlString];
    return [XML dictionaryFromXML:xmlDoc];
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号