使用NSXMLParser解析多级XML

时间:2014-04-14 20:28:07

标签: ios objective-c xml uitableview nsxmlparser

首先,如果术语不正确,请原谅。我正在尝试将来自旧金山BART系统的XML提要解析为UITableView,以便了解解析的工作原理。解析如下的简单提要非常简单。

<?xml version="1.0" encoding="utf-8" ?> 
<root>
  <uri><![CDATA[ http://api.bart.gov/api/sched.aspx?cmd=special ]]></uri>
  <holidays>
    <holiday>
      <name>New Year's Day (2009)</name> 
      <date>01/01/2009</date> 
      <schedule_type>Sunday</schedule_type> 
    </holiday>
    <holiday>
      <name>Presidents' Day</name> 
      <date>02/16/2009</date> 
      <schedule_type>Saturday</schedule_type> 
    </holiday>

我在那里感到非常自信。问题是现在我已经转移到更复杂的格式,如下所示。

<?xml version="1.0" encoding="utf-8" ?> 
<root>
  <uri><![CDATA[ http://api.bart.gov/api/etd.aspx?cmd=etd&orig=RICH ]]></uri>
  <date>03/30/2011</date> 
  <time>02:43:27 PM PDT</time> 
  <station>
    <name>Richmond</name> 
    <abbr>RICH</abbr> 
  <etd>
    <destination>Fremont</destination> 
    <abbreviation>FRMT</abbreviation> 
    <estimate>
      <minutes>5</minutes> 
      <platform>2</platform> 
      <direction>South</direction> 
      <length>6</length> 
      <color>ORANGE</color> 
      <hexcolor>#ff9933</hexcolor> 
      <bikeflag>1</bikeflag> 
    </estimate>
    <estimate>
    <minutes>20</minutes> 
      <platform>2</platform> 
      <direction>South</direction> 
      <length>6</length> 
      <color>ORANGE</color> 
      <hexcolor>#ff9933</hexcolor> 
      <bikeflag>1</bikeflag> 
    </estimate>
  </etd>
  <etd>
    <destination>Millbrae</destination> 
    <abbreviation>MLBR</abbreviation> 
    <estimate>
      <minutes>Leaving</minutes> 
      <platform>2</platform> 
      <direction>South</direction> 
      <length>10</length> 
      <color>RED</color> 
      <hexcolor>#ff0000</hexcolor> 
      <bikeflag>1</bikeflag> 
    </estimate>
  </etd>
 </station>
 <message /> 
</root>

我遇到的实际问题是如何在didStartdidEnd方法中构建填充我的tableview的数组,因为这是一个更复杂的结构。我所拥有的是如下(在我沮丧到可以寻求帮助之前的结束审判)并且远非正确

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {


element = elementName;

if ([element isEqualToString:@"station"]) {

    station = [[NSMutableDictionary alloc] init];
    name   = [[NSMutableString alloc] init];

}

if ([element isEqualToString:@"etd"]) {

    etd    = [[NSMutableDictionary alloc] init];
    destination   = [[NSMutableString alloc] init];

}

if ([element isEqualToString:@"estimate"]) {

    estimate    = [[NSMutableDictionary alloc] init];
    minutes   = [[NSMutableString alloc] init];
}

}

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

if ([elementName isEqualToString:@"station"]) {
    [station setObject:name forKey:@"name"];

    [data addObject:[station copy]];

}

if ([elementName isEqualToString:@"etd"]) {
    [etd setObject:destination forKey:@"destination"];        
    //[data addObject:[etd copy]];

}

if ([elementName isEqualToString:@"estimate"]) {
    [estimate setObject:minutes forKey:@"minutes"];
    //[data addObject:[estimate copy]];
}
}

我理解上面的内容是为每个元素创建一个单独的数组。最终目标是从车站名称向下钻取到目的地,再到离开&#34; x分钟&#34;。此外,我没有使用XCODE,因为大多数魔术都发生在我身上,有很多解析简单XML的教程,SO有很多关于简单结构的问题以及许多建议使用另一个解析器。这些不是我的选择,我只限于没有XCODE或IB的纯代码。这里的最后一个问题是我将如何构建我的最终数组以允许深入挖掘数据结构?

2 个答案:

答案 0 :(得分:0)

这不是一个直接的答案,但是,从我的经验来看,NSXMLParser越来越难以深入挖掘xml,我的解决方案始终使用XMLDictionary。虽然这不能解决您的问题但XMLDictionary确实使用NSXMLParser,因此如果您下载文件,您将能够看到它们如何处理更复杂的XML结构。

XMLDictionary示例

请记住#import&#34; XMLDictionary.h&#34;

NSString *googleString = @"http://www.google.com/"; // your xml url
NSDictionary *xml = [NSDictionary dictionaryWithXMLString:googleString];

然后你可以浏览字典来检索你想要的数据。

答案 1 :(得分:0)

看起来像走开,回来新思想仍然有奇迹。这是我提出的解决方案。不太难。

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {


element = elementName;

if ([element isEqualToString:@"station"]) {

    stationArray = [[NSMutableArray alloc] init];

    station = [[NSMutableDictionary alloc] init];
    name   = [[NSMutableString alloc] init];

}

else if ([element isEqualToString:@"etd"]) {

    destinationArray    = [[NSMutableArray alloc] init];
    destination   = [[NSMutableString alloc] init];

}

else if ([element isEqualToString:@"estimate"]) {

    estimateArray    = [[NSMutableArray alloc] init];
    minutes   = [[NSMutableString alloc] init];


}

}

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

///// Add Arrays to Dictionary, then Copy back to Array that sorts the Table

if ([elementName isEqualToString:@"station"]) {
    [station setObject:name forKey:@"name"];
    [station setObject:destinationArray forKey:@"destination"];
    [station setObject:estimateArray forKey:@"minutes"];
    [data addObject:[station copy]];

}

///// Add Destinations to an array

else if ([elementName isEqualToString:@"etd"]) {
    [destinationArray addObject:destination];


}

///// Add minutes to an array

else if ([elementName isEqualToString:@"estimate"]) {
    [estimateArray addObject:minutes];


}

}