2

我正在使用NSXMLParser以以下结构解析我的 XML:

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

我想使用cp_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];
    }
}

非常感谢您的关注。

4

1 回答 1

0

问题是您在将实际值读入currentElementValue之前将currentElementValue添加到_codepoint ,即您在启动cp_value时将其添加。你应该在委托方法中将currentElementValue添加到_codepoint 。然后你会得到预期的结果。像这样修改你的代码:didEndElement:

- (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 将存储属性。在你的情况下ucsjis208

于 2013-01-23T07:27:22.760 回答