如何在iPhone上解析多个.xml文件?

3
这是我第一次接触XML,如果我的问题质量不高,请不要对我太苛刻。我正在开发一个应用程序,通过从服务器获取的XML文件检索所有数据。
在发布问题之前,我阅读了一些有关解析XML文件的教程。但是当我开始在我的应用程序中实现它时,当我尝试解析第二个XML文件等时,我完全感到困惑。
现在,我想使用一些截图来解释我的应用程序流程,以便每个人都可以理解我想要什么。
  1. 第一个视图
  2. 第二个视图
  3. 第三个视图
现在,当我在第一个视图中点击任何一行时,它会转到第二个视图并在第二个视图中显示所有相关数据。当我在第二个视图中点击任何项目时,它会转到第三个视图并显示有关该特定项目的详细信息。
在解释应用程序流程之后,现在我展示了我到目前为止尝试过的代码。按照教程,我只是简单地将类(XMLParser,Book)拖到我的应用程序中进行测试。
代码:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 {
NSURL *url = [[NSURL alloc] initWithString:@"Firstviewxmlurl"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
XMLParser *parser = [[XMLParser alloc] initXMLParser];
[xmlParser setDelegate:parser];
BOOL success = [xmlParser parse];
if(success)
    NSLog(@"No Errors");
else
    NSLog(@"Error Error Error!!!");
 }

现在我的XMLParser.m代码是:
- (XMLParser *) initXMLParser {

[super init];

appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

return self;
  }

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

if([elementName isEqualToString:@"Collections"]) {
    //Initialize the array.
    appDelegate.books = [[NSMutableArray alloc] init];
}
else if([elementName isEqualToString:@"Collection"]) {

    //Initialize the book.
    aBook = [[Book alloc] init];

    //Extract the attribute here.
    aBook.bookID = [[attributeDict objectForKey:@"id"] integerValue];

    NSLog(@"Reading id value :%i", aBook.bookID);
}

NSLog(@"Processing Element: %@", elementName);
    }

   - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 

if(!currentElementValue) 
    currentElementValue = [[NSMutableString alloc] initWithString:string];
else
    [currentElementValue appendString:string];

NSLog(@"Processing Value: %@", currentElementValue);
}

 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
   namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if([elementName isEqualToString:@"Collections"])
    return;
if([elementName isEqualToString:@"Collection"]) {
    [appDelegate.books addObject:aBook];

    [aBook release];
    aBook = nil;
}
else 
    [aBook setValue:currentElementValue forKey:elementName];

[currentElementValue release];
currentElementValue = nil;
  }

最终我的第一个视图类代码为:
    #pragma mark Table Methods

  - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  {
return 1;
  }


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
 {
//return [tblViewData count];
return [appDelegate.books count];
 }

  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    {
static NSString *CellIdentifier = @"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil)
{
    cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
    cell.selectionStyle=UITableViewCellSelectionStyleGray;
    cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
}
//cell.textLabel.text=[[tblViewData objectAtIndex:indexPath.row]
                    // stringByReplacingOccurrencesOfString:@"*" withString:@""];
   Book *aBook = [appDelegate.books objectAtIndex:indexPath.row];

cell.textLabel.text = aBook.title;

if([deviceType isEqualToString:@"ipad"])
{
    [cell.textLabel setFont:[UIFont fontWithName:@"Helvetica-Bold" size:20]];
}
//cell.textLabel.font=[UIFont fontWithName:@"Walkway_SemiBold" size:16];
return cell;
   }

在实现了上述所有代码后,我得到了这个结果。现在我很困惑如何传递我的第二个视图xml文件的url以及第三个视图的url。我的xml文件格式如下:
第一个xml文件。
 <?xml version="1.0" encoding="UTF-8"?>
<Collections> <Collection id="5"><title>Allegroo</title> </Collection>

第二个 XML 文件。
 <?xml version="1.0" encoding="UTF-8"?>
 <Collection id="5"><colletciontitle>Allegroo</colletciontitle>  <weaveimage>"imageurl"   </weaveimage><Rug id="48"><Rugthumb>"firstimageurl"</Rugthumb><RugSku>AL-637</RugSku></Rug><Rug id="51"><Rugthumb>"Secondimageurl"</Rugthumb><RugSku>AL-641</RugSku></Rug>

第三个 XML 文件。
  <?xml version="1.0" encoding="UTF-8"?>
 <Rug id="47"><Rugmainimage>"imageurl"</Rugmainimage> <Rugtitle>AL-636 Aged Indigo / Vintage Beige</Rugtitle> <Rugdiscription>Hand Knotted
  Distressed Wool Pile / Cotton Foundation </Rugdiscription><Availablesizes><Size>10x14</Size><Size>12x15</Size><Size>2x3</Size><Size>3x5</Size><Size>4x6</Size><Size>6x9</Size><Size>8x10</Size><Size>9x12</Size><Runner>2'6"x10'</Runner><Runner>2'6"x12'</Runner><Runner>2'6"x8'</Runner></Availablesizes></Rug>

如果有关于我的问题的链接或示例代码以及建议方面的任何帮助,将不胜感激。谢谢。


1
最简单的方法是您可以定义一个int变量,在解析之前检查该变量的值。 - Baby Groot
你说得对,但我不确定如何在AppDelegate中传递多个XML文件的URL。 - jamil
1
据我所理解,你的代码中似乎不需要在AppDelegate中解析XML。你可以在viewDidLoad或者table row被选中时进行解析。然后将这个值存储在数组中,你可以在AppDelegate中定义并根据需要进行修改。 - Baby Groot
请详细回答,我认为您的方法符合我的要求。 - jamil
2个回答

2
嗯,简而言之,您想按顺序解析多个URL?
答案如下:
  1. Use a variable / identifier in appDelegate that tells you which xml is being parsed.
  2. Use your xml parser as delegate class object
  3. Use delegate method to swich to next xml parsing

     - (void)parserDidEndDocument:(NSXMLParser *)parser {
         // Change URL accordingly 
         NSURL *url = [[NSURL alloc] initWithString:@"Firstviewxmlurl"];
         NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
         XMLParser *parser = [[XMLParser alloc] initXMLParser];
         [xmlParser setDelegate:parser];
          BOOL success = [xmlParser parse];
    }
    

1
谢谢您的回答,但请您能否为我简化一下您的回答?因为我说过我的第一个URL可以工作,并且它在TableView中显示数据。现在我想要实现的是,当我点击UITableView中的任何一行时,使用第二个URL在第二个视图中显示数据。 - jamil

1

我添加了一些代码以方便您理解。请根据您的情况进行实现。下面的代码仅供参考,因为我还没有进行所有必要的更改,您需要先理解然后再相应地进行实现。

//int i = 0;   // in AppDelegate

代码:

//Or ViewDidLoad Method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
 int = 1;    //For First View
NSURL *url = [[NSURL alloc] initWithString:@"Firstviewxmlurl"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
XMLParser *parser = [[XMLParser alloc] initXMLParser];
[xmlParser setDelegate:parser];
BOOL success = [xmlParser parse];
if(success)
    NSLog(@"No Errors");
else
    NSLog(@"Error Error Error!!!");
 }

XMLParser.m

- (XMLParser *) initXMLParser 
    {  
      [super init];
      appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 
      return self;
    }

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

    if([elementName isEqualToString:@"Collections"]) 
   {
        //Initialize the array.
      if (int == 1)
        appDelegate.books = [[NSMutableArray alloc] init];

      else if (int == 2)
        appDelegate.secondArray = [[NSMutableArray alloc] init];

      else if (int == 3)
        appDelegate.thirdArray = [[NSMutableArray alloc] init];
    }

    else if([elementName isEqualToString:@"Collection"]) 
  {
         if (i == 1)
        {
          //Initialize the book.
          aBook = [[Book alloc] init];

          //Extract the attribute here.
          aBook.bookID = [[attributeDict objectForKey:@"id"] integerValue];

          NSLog(@"Reading id value :%i", aBook.bookID);
        }

         else if (i == 2)
        {
           //Second Xml 
        }

        else if (i == 3)
       {
           //Third Xml
       }

    }

  NSLog(@"Processing Element: %@", elementName);
 }


- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
    //Check condition 
    if(!currentElementValue) 
        currentElementValue = [[NSMutableString alloc] initWithString:string];
    else
        [currentElementValue appendString:string];

    NSLog(@"Processing Value: %@", currentElementValue);
    }

     - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
       namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
//Check COndition
    if([elementName isEqualToString:@"Collections"])
        return;
    if([elementName isEqualToString:@"Collection"]) {
        [appDelegate.books addObject:aBook];

        [aBook release];
        aBook = nil;
    }
    else 
        [aBook setValue:currentElementValue forKey:elementName];

    [currentElementValue release];
    currentElementValue = nil;
      }

嗨,当我在viewdidload中调用URL时,在tableview中不显示任何数据,我认为viewdidload和tableview代理方法同时调用,这就是为什么它显示我的书籍数组为空的原因。 - jamil
确保在解析完成后重新加载表格 [tableView reloadData]; 并检查数组中的值是否有数据。 - Baby Groot
1
你展示的books数组是这个类的一个对象,而你在其他类中解析xml。你是将值存储在这个对象还是这个类中?我不确定。最好在AppDelegate中定义该数组。 - Baby Groot
1
你似乎不仅对 XML,也对 Xcode 是新手。你想根据选择获取数据,所以你需要在 tableview didselectrow 中,在你的第一个类中分配二级类的数组。 - Baby Groot
让我们在聊天中继续这个讨论 - jamil
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接