如何使用NSXMLParser将NSMutableDictionary中的键值对设置为XML属性元素值

时间:2013-01-23 06:19:45

标签: ios xml xcode nsxmlparser

我正在使用 NSXMLParser 来解析我的XML,结构如下:

<characters>
    <character>
        <literal>本</literal>
        <codepoint>
            <cp_value cp_type="ucs">672c</cp_value>
            <cp_value cp_type="jis208">43-60</cp_value>
        </codepoint>
    </character>
</characters>

我想将cp_value元素的attribute_value用作关键字,使用元素值(例如672c)作为值,并将此键值对放在我的NSMutableDictionary *_codepoint中。解析后,我希望结果(在控制台中)看起来像这样:

_codepoint: {
 "ucs"=672c;
 "jis208"=43-60;
}

由于我已经实现了解析器(代码如下),我在控制台中得到了这个:

2013-01-22 22:12:46.199 MyApp[13391:c07] _codepoint: {
ucs = "\n        \n            ";
}
2013-01-22 22:12:46.201 MyApp[13391:c07] _codepoint: {
    jis208 = "\n        \n            672c\n            ";
}

首先 - 值和键不同步,其次,jis208元素的值没有被读入。其次,我不确定这些\ n和空白是什么。有人可以提一些建议吗?

我写的代码是:

- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qName
    attributes:(NSDictionary *)attributeDict
{
    if([elementName isEqualToString:@"characters"]) {
        appDelegate.characters = [[NSMutableArray alloc] init];
    } else if ([elementName isEqualToString:@"character"]) {
        aCharacter = [[Character alloc] init];
    } else if ([elementName isEqualToString:@"cp_value"]) {
        if (!_codepoint) _codepoint = [[NSMutableDictionary alloc] init];
        [_codepoint setValue:currentElementValue forKey:[attributeDict valueForKey:[[attributeDict allKeys] lastObject]]];
        NSLog(@"_codepoint: %@", _codepoint);
    }
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if (!currentElementValue) {
        currentElementValue = [[NSMutableString alloc] initWithString:string];
    } else {
        [currentElementValue appendString:string];
    }
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:@"characters"]
        // cp_values will be copied from a local NSMutableDictionary *_codepoint
        || [elementName isEqualToString:@"codepoint"]
        ) return;    
    if ([elementName isEqualToString:@"character"]) {
        [appDelegate.characters addObject:aCharacter];
        [aCharacter release];
    } else if ([elementName isEqualToString:@"cp_value"]){
        [aCharacter.codepoint addObject:_codepoint];
    }
}

非常感谢您的光临。

1 个答案:

答案 0 :(得分:0)

问题在于,在将实际值添加到 currentElementValue 之前,您要将 currentElementValue 添加到 _codepoint ,即在 cp_value时添加它已启动。你应该在didEndElement:委托方法中将 currentElementValue 添加到 _codepoint 。然后你会得到预期的结果。修改你的代码如下:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if([elementName isEqualToString:@"characters"]) {
        appDelegate.characters = [[NSMutableArray alloc] init];
    } else if ([elementName isEqualToString:@"character"]) {
        aCharacter = [[Character alloc] init];
    } else if ([elementName isEqualToString:@"cp_value"]) {
        if (!_codepoint) _codepoint = [[NSMutableDictionary alloc] init];
    currentAttributeKey = [[NSMutableString alloc]initWithString:[attributeDict valueForKey:[[attributeDict allKeys] lastObject]]];
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if (!currentElementValue) {
        currentElementValue = [[NSMutableString alloc] initWithString:string];
    } else {
        [currentElementValue appendString:string];
    }
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:@"characters"] || [elementName isEqualToString:@"codepoint"]) 
        return;    
    if ([elementName isEqualToString:@"character"]) {
        [appDelegate.characters addObject:aCharacter];
        [aCharacter release];
    } else if ([elementName isEqualToString:@"cp_value"]){
        [_codepoint setValue:[[currentElementValue componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsJoinedByString:@""] forKey:currentAttributeKey];
        currentElementValue = [[NSMutableString alloc]init];
        NSLog(@"_codepoint: %@", _codepoint);
        [aCharacter.codepoint addObject:_codepoint];
    }
}

其中 currentAttributeKey 是NSMutableString,用于存储属性。在您的情况下 ucs jis208