1

我试图解析 XML(这看起来不错)并在 Iphone 上填充表视图。我正在使用苹果 siesmec 示例。我的 XML 看起来像这样,大约有 10 个条目从艺术家 1 到艺术家 10

<promo> <id> 42 </id> <artistname> artist1 </artistname> <img> http://address.com/avatar_42.jpg </img> </promo>

如果我输入断点,我可以看到所有正确的名称,但是当解析完成时,我表中的所有 10 个单元格都会显示“artist10:

xml 的代码作为表视图控制器在文件中。你能看到任何明显的愚蠢错误吗?

#pragma mark Parser constants
    // Limit the number of parsed earthquakes to 50.

static const const NSUInteger kMaximumNumberOfEarthquakesToParse = 50;

static NSUInteger const kSizeOfEarthquakeBatch = 10;

// Reduce potential parsing errors by using string constants declared in a single place.
static NSString * const kArtistName = @"artistname";
static NSString * const kEntryElementName = @"promo";
static NSString *const kEntryElementID =@"id";
static NSString *const kEntryElementImg=@"img";


- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    if (parsedPromoListCounter >= kMaximumNumberOfEarthquakesToParse) {
        // Use the flag 
  didAbortParsing = YES;
        [parser abortParsing];
    }
    if ([elementName isEqualToString:kEntryElementName]) {
        PromoListItem *promoitem = [[PromoListItem alloc] init];
        self.currentPromoListObject = promoitem;
        [promoitem release];

} else if ([elementName isEqualToString:kEntryElementImg]) {
  //nothing for now
    } else if ([elementName isEqualToString:kArtistName] || [elementName isEqualToString:kEntryElementImg] || [elementName isEqualToString:kEntryElementID]) {
  accumulatingParsedCharacterData = YES;

        // The mutable string needs to be reset to empty.
        [currentParsedCharacterData setString:@""];
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {     
 if ([elementName isEqualToString:kEntryElementName]) {
  [self.currentParseBatch addObject:self.currentPromoListObject];
  parsedPromoListCounter++;
  if (parsedPromoListCounter % kSizeOfEarthquakeBatch == 0) {
   [self performSelectorOnMainThread:@selector(addPromosToList:) withObject:self.currentParseBatch waitUntilDone:NO];
   self.currentParseBatch = [NSMutableArray array];
  }
 } else if ([elementName isEqualToString:kArtistName]) {
  self.currentPromoListObject.artistName=self.currentParsedCharacterData;
 } else if ([elementName isEqualToString: kEntryElementID]) {
  self.currentPromoListObject.artistID = self.currentParsedCharacterData;
 } else if ([elementName isEqualToString:kEntryElementImg]) {

  self.currentPromoListObject.imgLink=self.currentParsedCharacterData;
 }
 // Stop accumulating parsed character data. We won't start again until specific elements begin.
 accumulatingParsedCharacterData = NO;
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
   if (accumulatingParsedCharacterData) {
    // If the current element is one whose content we care about, append 'string'
    // to the property that holds the content of the current element.
    [self.currentParsedCharacterData appendString:string];
   }
  }`

这就是我填充表格视图的方式

#pragma mark Table View Methods

// The number of rows is equal to the number of earthquakes in the array.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [self.promoList count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

 // Each subview in the cell will be identified by a unique tag.
    static NSUInteger const kartistNameLabelTag = 2;

    // Declare references to the subviews which will display the earthquake data.
    UILabel *artistNameLabel = nil;


 static NSString *kpromoCellID = @"promoCellID";   

   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kpromoCellID];
 if (cell == nil) {
        // No reusable cell was available, so we create a new cell and configure its subviews.
  cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kpromoCellID] autorelease];

        artistNameLabel = [[[UILabel alloc] initWithFrame:CGRectMake(10, 3, 190, 20)] autorelease];
  artistNameLabel.tag = kartistNameLabelTag;
        artistNameLabel.font = [UIFont boldSystemFontOfSize:14];
        [cell.contentView addSubview: artistNameLabel];

 } else {
        // A reusable cell was available, so we just need to get a reference to the subviews using their tags.
        artistNameLabel = (UILabel *)[cell.contentView viewWithTag:kartistNameLabelTag];

    }

    // Get the specific promo for this row.
 PromoListItem *promo = [promoList objectAtIndex:indexPath.row];

    // Set the relevant data for each subview in the cell.
    artistNameLabel.text =promo.artistName;

 return cell;

} 
4

1 回答 1

0

这让我很生气,所以我采取了不同的方法。

这是我做的代码实现

我不确定哪种方法更好。也许有人会对这个有意见?

我无法使用的第一个版本似乎让您可以更好地控制要解析的字符数据。这是我能看到的唯一真正的好处。

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

    if([elementName isEqualToString:@"promolist"]) {
        //Initialize the array.
        promoList = [[NSMutableArray alloc] init];
    }
    else if([elementName isEqualToString:kEntryElementName]) {

        //Initialize the book.
        //aBook = [[Book alloc] init];
        //aBook =[[PromoListItem alloc] init];
        PromoListItem *promo = [[PromoListItem alloc] init];
        self.currentPromoListObject = promo;
        [promo release];

    }

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

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

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

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

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

    if([elementName isEqualToString:@"promolist"])
    {
        [self.tableView reloadData];
        return;
    }

    //There is nothing to do if we encounter the promo element here.
    //If we encounter the promo element howevere, we want to add the book object to the array
    // and release the object.
    else if([elementName isEqualToString:kEntryElementName]) {
        [promoList addObject:currentPromoListObject];

        [currentPromoListObject release];
        currentPromoListObject = nil;
    }
    else{
        [currentPromoListObject setValue:currentParsedCharacterData forKey:elementName];

        }
    [currentParsedCharacterData release];
    currentParsedCharacterData = nil;

}
于 2010-02-04T14:45:52.003 回答