Iphone 使用NSXMLParser解析XML

Iphone 使用NSXMLParser解析XML,iphone,objective-c,xml,parsing,Iphone,Objective C,Xml,Parsing,我有一个关于xml解析的问题。通常,XML文件样式如下所示: <person> <name> abc </name> <age> 19 </age> <gender> male </gender> </person> 来识别元素 现在,我面临一种xml文件样式,如: <person> <element type="name&quo

我有一个关于xml解析的问题。通常,XML文件样式如下所示:

<person>
     <name> abc </name>
     <age> 19 </age>
     <gender> male </gender> 
</person>
来识别元素

现在,我面临一种xml文件样式,如:

<person>
     <element type="name">abc</element>
     <element type="age">19</element>
     <element type="gender">male</element> 
</person>
所以我试着用

if ([elementName isEqualToString:@"element"]) {
   if ([[attributeDict objectForKey:@"type"] isEqualToString:@"name"){
      .....
   }
}
要识别“name”,但它给了我一个none值,如果我尝试获取“name”的值,则没有任何结果

那么,有人对解决这个问题有什么建议吗?谢谢

附:这是我的部分代码

- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
    attributes:(NSDictionary *)attributeDict {
    
    
    if ( [elementName isEqualToString:@"area"]) {
        if ([[attributeDict objectForKey:@"type"] isEqualToString:@"location"]) {
            NSString *description = [attributeDict objectForKey:@"description"];
            
            NSArray *lineEntry = [[NSArray alloc] initWithObjects:description,nil ];
            NSArray *lineKeys = [[NSArray alloc] initWithObjects:@"description",nil];
            NSDictionary *dictItem = [[NSDictionary alloc] initWithObjects:lineEntry forKeys:lineKeys];
            
            [lineKeys release];
            [lineEntry release];
            
            [dataLoad addObject:dictItem];
            [dictItem release];
        }
        
    }
    
    if ([elementName isEqualToString:@"forecast-period"]) {
        
        NSString *index = [attributeDict objectForKey:@"index"];
        NSString *time = [attributeDict objectForKey:@"start-time-local"];
        

        NSArray *indexEntry = [[NSArray alloc] initWithObjects:index,time,nil];
        NSArray *indexKey = [[NSArray alloc] initWithObjects:@"index",@"start-time-local",nil];

        NSDictionary *dicIndex = [[NSDictionary alloc] initWithObjects:indexEntry forKeys:indexKey];
        
        [indexEntry release];
        [indexKey   release];
        
        [weatherLoad addObject:dicIndex];
        [dicIndex release];
        
        
    }
}
这两个部分都很好,但如果我尝试获取“预测图标代码”、“空气温度最低”、“空气温度最高”、“精度”则不起作用


1.
12
24
晴朗的
有什么建议吗?顺便说一句,整个xml文件都在这里:

阅读Apple事件驱动xml编程中“属性处理”一节,您将得到答案

我假设您希望将预测期的所有“元素”添加到您将索引和开始时间放在其中的同一个字典中

您在问题中发布的原始基本if语句没有问题,但问题在于使用NSXMLParser时,每个xml标记(“预测期”、“元素”、“文本”等)都会触发didStartElement方法

因为有多个“预测期”标记和多个“元素”标记,所以代码需要跟踪当前父标记/对象是什么。处理“forecast period”标记后,didStartElement将为以下“element”标记再次激发。在该调用中,方法参数将不会指示此“元素”是“预测期”的子元素,且“索引”为1。你的代码必须跟踪这一点

此外,由于“element”标记具有实际值(例如type=precis的“Sunny”),因此必须实现foundCharacters和didEndElement

在didEndElement中,根据当前目标对象是什么,必须将数据放在适当的位置。如果是“预测期”的结束,什么也不做(它没有价值)。如果是“element”标记的结尾,则必须获取foundCharacters捕获的值,并将其添加到weatherLoad中的最后一个字典中。这也意味着您需要改为使用NSMutableDictionary,而不是NSDictionary


@itsaoutcode提供给您的链接是上述所有内容的一个很好的示例(位于“处理属性”之上)部分。

您确定使用的是NSXMLParser吗?它是一种SAX风格的解析器,意味着每次它到达元素的开头/结尾时都会得到一个回调。没有API可以按名称要求它获取元素。NSXML听起来更像您所说的。您发布的代码的一小部分看起来很好。问题可能在其他地方。发布您正在实现的所有NSXMLParser委托方法的所有代码。是的,我使用的是NSXMLParser。原始XML不是这么简单,我只是对这种XML样式感到困惑。如果XML文件没有,就没有问题。委托很好,我很确定“如果([elementName IseQualtString:@“element”]){如果([[attributeDict objectForKey:@“type”]IseQualtString:@“name”){……}}整个代码都非常大>@David-正如aBitObvious所建议的,这是一种方法,但在其他部分可能会有问题。
if ([elementName isEqualToString:@"element"]) {
   if ([[attributeDict objectForKey:@"type"] isEqualToString:@"name"){
      .....
   }
}
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
    attributes:(NSDictionary *)attributeDict {
    
    
    if ( [elementName isEqualToString:@"area"]) {
        if ([[attributeDict objectForKey:@"type"] isEqualToString:@"location"]) {
            NSString *description = [attributeDict objectForKey:@"description"];
            
            NSArray *lineEntry = [[NSArray alloc] initWithObjects:description,nil ];
            NSArray *lineKeys = [[NSArray alloc] initWithObjects:@"description",nil];
            NSDictionary *dictItem = [[NSDictionary alloc] initWithObjects:lineEntry forKeys:lineKeys];
            
            [lineKeys release];
            [lineEntry release];
            
            [dataLoad addObject:dictItem];
            [dictItem release];
        }
        
    }
    
    if ([elementName isEqualToString:@"forecast-period"]) {
        
        NSString *index = [attributeDict objectForKey:@"index"];
        NSString *time = [attributeDict objectForKey:@"start-time-local"];
        

        NSArray *indexEntry = [[NSArray alloc] initWithObjects:index,time,nil];
        NSArray *indexKey = [[NSArray alloc] initWithObjects:@"index",@"start-time-local",nil];

        NSDictionary *dicIndex = [[NSDictionary alloc] initWithObjects:indexEntry forKeys:indexKey];
        
        [indexEntry release];
        [indexKey   release];
        
        [weatherLoad addObject:dicIndex];
        [dicIndex release];
        
        
    }
}
<forecast-period index="1" start-time-local="2010-11-19T00:00:00+11:00" end-time-local="2010-11-20T00:00:00+11:00" start-time-utc="2010-11-18T13:00:00Z" end-time-utc="2010-11-19T13:00:00Z">
<element type="forecast_icon_code">1</element>
<element type="air_temperature_minimum" units="Celsius">12</element>
<element type="air_temperature_maximum" units="Celsius">24</element>
<text type="precis">Sunny.</text>
</forecast-period>