Parsing attributes with same name but in different

2019-09-19 03:12发布

I have a php as follows:

<?php
    header("Content-Type: application/rss+xml; charset=ISO-8859-1");
    $ip=$_GET['ip'];
    $type=$_GET['type'];
    $rssfeed = '<?xml version="1.0" encoding="ISO-8859-1"?>';
    $rssfeed .= '<rss version="2.0">';
    $connection = mysql_connect('localhost','root')
    or die('Could not connect to database');
    mysql_select_db('Android')
    or die ('Could not select database');
    $query = "SELECT * FROM User_Upload_Table WHERE Status='Approved' and Content_Type='$type' ORDER BY Approved_Time desc";
    $result = mysql_query($query) or die ("Could not execute query");
    while($row = mysql_fetch_array($result)) {
            extract($row);
            $rssfeed .= "<channel>";
            $rssfeed .= "<title>" .$row[Content_Name] ."</title>";
            $rssfeed .= '<link>http://'.$ip .$row[Content_Path] .$row[Status] . '/' .$row[Content_Name] . '</link>';
            if($type == "Video"){
          $rssfeed .= '<description>' .$row[Duration]. '</description>';
            }
            $rssfeed .= '<category>' .$row[Description]. '</category>';
            $rssfeed .= '<rating>' .$row[Rating]. '</rating>';
            $rssfeed .= '<generator>' .$row[Vote_Count]. '</generator>';
            $rssfeed .= '<language></language>';
            if($type == "Video"){
              $name = $row[Content_Name];
              $subName = substr($name, 0, strpos($name, '.'));
              $rssfeed .= '<image>http://'.$ip.'/Android/'.$type.'/'.$subName.'.jpg</image>';
            } else {
              $rssfeed .= '<image>http://'.$ip.'/Android/'.$type.'/Approved.jpg</image>';
            }
            $rssfeed .= '<copyright>Copyright 2011</copyright>';
            $rssfeed .= '<item>';
            $rssfeed .= '<title>Pre-Roll</title>';
            $rssfeed .= '<link>http://'.$ip.'/Android/Video/Approved/MERCEDES_BENZ.3gp</link>';
            $rssfeed .= '<description>Post-Roll</description>';
            $rssfeed .= '<source>http://'.$ip.'/Android/Video/Approved/PG_Dawn_PGDN4582000_30.mp4</source>';
            $rssfeed .= '</item>';
            $rssfeed .= '</channel>';
    }
    $rssfeed .= '</rss>';
    echo $rssfeed;
?>

Here i have two fields with the name title, one in channel and the other in item attribute. How can I parse it separately. My parsing code is as follows:

  -(void)parseXMLFileAtURL:(NSString *)URL{

  NSURL *xmlURL = [NSURL URLWithString:URL];
  rssParser = [[NSXMLParser alloc]initWithContentsOfURL:xmlURL];
  [rssParser setDelegate:self];
  [rssParser setShouldProcessNamespaces:NO];
  [rssParser setShouldReportNamespacePrefixes:NO];
  [rssParser setShouldResolveExternalEntities:NO];
  [rssParser parse];
  NSLog(@"Parsed");
}

-(void)parserDidStartDocument:(NSXMLParser *)parser{

    NSLog(@"Found file and started parsing");
}


-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{

NSString *errorString = [NSString stringWithFormat:@"Unable to download feed from website (Error Code %i)", [parseError code]];
NSLog(@"Error parsing xml: %@", errorString);
UIAlertView *errorAlert = [[UIAlertView alloc]initWithTitle:@"Error loading content" message:errorString delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[errorAlert show];
}


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

  insideItem = FALSE;
  insideChannel = FALSE;

  rssElement      = [[NSMutableDictionary alloc]init];

  currentElement = [elementName copy];
  if ([elementName isEqualToString:@"channel"]) {

    title           = [[NSMutableString alloc]init];
    link            = [[NSMutableString alloc]init];
    description     = [[NSMutableString alloc]init];
    copyright       = [[NSMutableString alloc]init];
    image           = [[NSMutableString alloc]init];
  }
}


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

  if ([elementName isEqualToString:@"channel"]) {

    [rssElement setObject:title                 forKey:@"title"];
    [rssElement setObject:link                  forKey:@"link"];
    [rssElement setObject:description           forKey:@"description"];
    [rssElement setObject:copyright             forKey:@"copyright"];
    [rssElement setObject:image                 forKey:@"image"];

    [item addObject:[rssElement copy]];
    NSLog(@"adding stories %@", title);

  }
}


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

  if ([currentElement isEqualToString:@"title"]) {
    [title appendString:string];
  }else if ([currentElement isEqualToString:@"link"]) {
    [link appendString:string];
  }else if ([currentElement isEqualToString:@"description"]) {
    [description appendString:string];
  }else if ([currentElement isEqualToString:@"copyright"]) {
    [copyright appendString:string];
  }else if ([currentElement isEqualToString:@"image"]) {
     [image appendString:string];
  }
}

-(void)parserDidEndDocument:(NSXMLParser *)parser{

    NSLog(@"all done");
    NSLog(@"item array has %d items", [item count]);
    [tableView reloadData];
    NSLog(@"Finished Parsing");
}

Now, the problem is when I am displaying the feed in a table view, the two title fields are getting appended but I need to display only the title field of channel attribute.

Please help me and let me know what is that I am doing wrong.

The proper code will be of immense help in this regard.

2条回答
Fickle 薄情
2楼-- · 2019-09-19 03:52

I have fixed the problem. My current code which solved my issue is as follows:

-(void)parseXMLFileAtURL:(NSString *)URL{

    NSURL *xmlURL = [NSURL URLWithString:URL];
    rssParser = [[NSXMLParser alloc]initWithContentsOfURL:xmlURL];
    [rssParser setDelegate:self];
    [rssParser setShouldProcessNamespaces:YES];
    [rssParser setShouldReportNamespacePrefixes:NO];
    [rssParser setShouldResolveExternalEntities:NO];
    [rssParser setIsAccessibilityElement:YES];
    [rssParser parse];
}


-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{

    NSString *errorString = [NSString stringWithFormat:@"Unable to download feed from website (Error Code %i)", [parseError code]];
    UIAlertView *errorAlert = [[UIAlertView alloc]initWithTitle:@"Error loading content" message:errorString delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [errorAlert show];
}   


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

    currentElement = [elementName copy];

    if ([elementName isEqualToString:@"channel"]) {

        channelDictionary = [[NSMutableDictionary alloc]init];
        itemAttributeArray = [[NSMutableArray alloc]init];

        insideItem = FALSE;
    }else {
        if ([elementName isEqualToString:@"item"]) {


        insideItem = TRUE;
        itemDictionary = [[NSMutableDictionary alloc]init];
      }
   }
}

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

    key = [[NSMutableString alloc]init];
    key = [currentElement copy];

    value = [[NSMutableString alloc]init];
    [value setString:string];

    if (insideItem == TRUE) {  

        [itemDictionary setObject:value forKey:currentElement];
     }else{

        [channelDictionary setObject:value forKey:currentElement];

    }  

}

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

    if ([elementName isEqualToString:@"channel"]) {
        [channelDictionary setObject:itemAttributeArray forKey:@"item"];
        [channelAttributeArray addObject:[channelDictionary copy]];
    }else {
         if ([elementName isEqualToString:@"item"]){
             [itemAttributeArray addObject:[itemDictionary copy]];
             insideItem = FALSE;
        }
    }
}

-(void)parserDidEndDocument:(NSXMLParser *)parser{

     [tableView reloadData];
}  
查看更多
Viruses.
3楼-- · 2019-09-19 03:53

In didStartElement, push the current tag to a stack. In didEndElement, pop it from the stack. Then you can always check the stack for the parent element and distinguish between the channel's title element and the item's title element.

查看更多
登录 后发表回答