XML Parser组织键中的元素

时间:2014-08-08 23:54:04

标签: objective-c nsmutabledictionary

我正在读取xml文件中的现有元素,并使用键和对象在NSMutableDictionary中进行组织,我的xml文件的结构如下:

<?xml version="1.0"?>
<root>

    <elements>
        <element1>something 0</element1>
        <element2>somethingelse 0</element2>
        <element3>anotherthing 0</element3>
    </elements>

    <elements>
        <element1>something 1</element1>
        <element2>somethingelse 1</element2>
        <element3>anotherthing 1</element3>
    </elements>

    <elements>
        <element1>something 2</element1>
        <element2>somethingelse 2</element2>
        <element3>anotherthing 2</element3>
    </elements>

</root>

我的代码如下:

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{

    NSString *trim = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

    if(!currentString){       
        currentString = [[NSMutableString alloc] init];       
    }

    [currentString appendString:trim];

}


- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{

    if([elementName isEqualToString:@"root"]){

        currentString = nil;
        return;
    }

    if([elementName isEqualToString:@"elements"]){

        key++;
        currentString = nil;

    }else{
        NSString *keyp = [NSString stringWithFormat:@"%d",key];
        NSMutableArray *listForelements = elementsArray[keyp];

        if (keyp != nil) {
            listForelements = [NSMutableArray array];
            [elementsArray setValue:currentString forKey:keyp];   
        }

        [listForelements addObject:currentString];
        currentString = nil;
        return;   
    }
    currentString = nil;

数组elementsArray返回以下值:

 0 = "anotherthing 0";
 1 = "anotherthing 1";
 2 = "anotherthing 2";

而不是:

0 = 

"something 0"
"somethingelse 0"
"anotherthing 0"

1 = 

"something 1"
"somethingelse 1"
"anotherthing 1"

...

我如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

最近使用了大量的XML之后,我想说最好的办法是查看像Ono这样的库。使用内置的NSXMLParser和委托方法可以解析XML,但与使用Ono的以下解决方案相比,需要跟踪大量的事情。

此解决方案使用单个类方法,该方法接受XML NSData并返回NSDictionary。这个方法是在专用的解析类中创建的,无论它的价值如何。

#import "Ono.h"

+ (NSDictionary *)parseData:(NSData *)data
{
    NSError *docError;

    ONOXMLDocument *document = [ONOXMLDocument XMLDocumentWithData:data error:&docError];

    if (docError) {
        // handle document creation error
        NSLog(@"%@", docError.localizedDescription);
    }

    NSMutableDictionary *parsedData = [NSMutableDictionary dictionary];

    [document enumerateElementsWithXPath:@"//elements" usingBlock:^(ONOXMLElement *element, NSUInteger idx, BOOL *stop) {
        NSString *key = [NSString stringWithFormat:@"%d", idx];
        NSMutableArray *items = [NSMutableArray array];

        [element.children enumerateObjectsUsingBlock:^(ONOXMLElement *obj, NSUInteger idx, BOOL *stop) {
            NSString *trimmedString = [obj.stringValue stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
            [items addObject:trimmedString];
        }];

        [parsedData setObject:[items copy] forKey:key];
//        [parsedData setObject:[items copy] forKey:@(idx)]; if you wanted to use an NSNumber as the key

        [items removeAllObjects];

    }];

    return parsedData;
}

我们首先使用ONOXMLDocument方法创建+XMLDocumentWithData:error:。接下来,我们要检查文档是否已正确创建并正确处理错误。

创建NSMutableDictionary以存储已解析的数据,并由方法返回。

关于解析,我们首先枚举所有具有XPath ONOXMLElement的{​​{1}}实例。使用提供的XML,这给了我们3个项目。然后,我们使用枚举块提供的索引为要包含的数组创建一个密钥。我们也可以在代码中使用NSNumber作为评论。

接下来,我们创建一个elements来保存我们打算解析的内容字符串。我们需要枚举每个NSMutableArray节点的子项(element1element2element3)。为方便起见,我们使用elements作为参数ONOXMElement的类型,因此我们可以使用返回节点内容的obj属性。

如上所述,它根据所需的字符集进行修剪,然后将它添加到我们的items数组中。在枚举元素的子元素之后,我们将items数组的副本添加到字典中(因为它是不可变的,内容将在下一次迭代时更改)然后删除所有对象,使其在下一次迭代时为空。

完成所有迭代后,我们将返回已解析XML的字典。