我正在使用 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];
}
}
非常感谢您的光临。
答案 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