使用 NSXMLParser 解析 XML 的最有效方法

发布于 2024-12-09 07:02:05 字数 505 浏览 0 评论 0原文

我试图找出使用 xmlparser delegate 解析大型 xml 数据集的最佳方法..(基本上我到底要把数据放入什么?)

xml 数据将如下所示。

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

我正在寻找高水平的响应,这样我就可以离开并做更多的研究,因为它们显然是解决这个问题的几种不同的方式。我想知道存储从 NSXMLParser 返回的数据的最佳/最有效的方法想要一些我能够缓存的东西...

到目前为止,我一直在查看 NSMutabledictionarys 但是听说这可能不合适,所以我现在开始考虑创建自己的对象..但是从我的解析委托是只与字符串兼容..所以如果我有一个布尔值,我不能将它放入我的对象中..任何帮助将不胜感激,因为我有点不知所措。

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 that 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.

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

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

发布评论

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

评论(1

旧梦荧光笔 2024-12-16 07:02:05

我已经实现了一个足够高效的 XML 到 NSDictionary 解析器。如果需要,您可以将其作为 NSMutableDictionary 返回。我目前没有 github 或任何东西,所以我将在这里内联发布代码。它利用 TBXML XML 解析库 (没有 XPath 支持和只读解析,但相当高效和高级)。

编辑:我刚刚意识到,我的解析器是用来解析元素名称和元素内的文本的,而不是元素属性,这就是 XML 数据集的布局方式。不幸的是,下面的代码不会解析属性。不过,您已经有了一个起点,您可以更改使用 ->firstChild->nextSibling 读取属性的代码。


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:@"&"
      withString:@"&"]
     stringByReplacingOccurrencesOfString:@"
"
            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];
}

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:@"&"
      withString:@"&"]
     stringByReplacingOccurrencesOfString:@"
"
            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];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文