iOS NSXMLParser值与类别即。 tableviews </product>中的<product category =“ABC”>

时间:2012-12-14 17:07:27

标签: ios xml xml-parsing tableview xcode4.5

我有一个XML,它代表一个产品目录,其中每个产品属于一个类别。即:

<Product category="ABC">
 <Item_number>123</Item_number>
</Product>

<Product category="ABC">
 <Item_number>456</Item_number>
</Product>

<Product category="XYZ">
 <Item_number>789</Item_number>
</Product>

我创建了一个用于存储数据的类,然后将一个实例放入一个数组中。*然后将其显示到tableview上。目前,tableview显示了Item_numbers列表:D

我想要达到的目标是一样的,但我希望有两页。具有非重复(唯一)类别(即ABC,XYZ)的主表视图,在第2页 - 详细表视图中,它将显示属于所选类别的item_number。喜欢这个..

主要表视图:

ABC >
XYZ >

详细表格视图(选择“ABC”):

123
456

(1)最好的方法是什么?

(2)我猜我的第一个障碍是从“ABC”类别中解析出来的值

    <Product category="ABC">

在我的实现中,当我只是调用时(当XML中的某个类别有点不同时以某种方式解析一个值),我得到了空白。

cell.textLabel.text = product.product;

(3)第二个是如何存储数据(或者我可以保持相同的方法*),用户可以从第一页中选择单个类别来引用详细的Tableview页面。


didStartElement的当前实现

- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
        if ( [elementName isEqualToString:@"Product"] ){
            self.currentProduct = [[Product alloc] init];
            self.storeCharacters = NO;
        } else  if ([elementName isEqualToString:@"Item_Number"]) {
            [self.currentString setString:@""];
            self.storeCharacters = YES;
        }
    }

1 个答案:

答案 0 :(得分:0)

关于解析category,当attributeselementName时,@"Product"<Products> <Product category="ABC"> <Item_number>123</Item_number> <Description>Coffee table</Description> </Product> <Product category="ABC"> <Item_number>456</Item_number> <Description>Lamp shade</Description> </Product> <Product category="XYZ"> <Item_number>789</Item_number> <Description>Orange chair</Description> </Product> </Products> 词典中检索到// this is our final result, an array of dictionaries for each categor @property (nonatomic, strong) NSMutableArray *categories; // these are just temporary variables used during the parsing @property (nonatomic, strong) NSMutableString *parserElementValue; @property (nonatomic, strong) NSMutableDictionary *parserProduct;

就“最佳方法”而言,您只需要决定您的数据结构。我可能会建议构建一个NSMutableArray,它是一个类别字典条目数组,每个类别一个,字典中的一个对象将是该类别中的一组产品。

一旦你有了这个结构,回答你的第三个问题可能是显而易见的。


好的,首先,您的XML确实需要一个外部标记,例如:

NSXMLParserDelegate

其次,假设您需要一组类别,并且对于每个类别,您需要一组产品,实现可能如下所示。首先,您需要一些属性,一个用于最终结果,另外两个用于解析期间使用的临时变量:

#pragma mark - NSXMLParser delegate methods

- (void)parserDidStartDocument:(NSXMLParser *)parser
{
    self.categories = [NSMutableArray array];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    NSArray *subElementNames = @[@"Item_number", @"Description"];

    if ([elementName isEqualToString:@"Product"])
    {
        // get the name of the category attribute

        NSString *categoryName = [attributeDict objectForKey:@"category"];
        NSAssert(categoryName, @"no category found");

        // search our array of dictionaries of cateogries to see if we have one with a name equal to categoryName

        __block NSMutableDictionary *parserCurrentCategory = nil;
        [self.categories enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            if ([categoryName isEqualToString:[obj objectForKey:@"name"]])
            {
                parserCurrentCategory = obj;
                *stop = YES;
            }
        }];

        // if we didn't find one, let's create one and add it to our array of cateogires

        if (!parserCurrentCategory)
        {
            parserCurrentCategory = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                    categoryName, @"name",
                                    [NSMutableArray array], @"items",
                                    nil];
            [self.categories addObject:parserCurrentCategory];
        }

        // Now let's add an entry to the items array for the product being added

        self.parserProduct = [NSMutableDictionary dictionary];
        [[parserCurrentCategory objectForKey:@"items"] addObject:self.parserProduct];
    }
    else if ([subElementNames containsObject:elementName])
    {
        self.parserElementValue = [NSMutableString string];
        [self.parserProduct setObject:self.parserElementValue forKey:elementName];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if (self.parserElementValue)
        [self.parserElementValue appendString:string];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:@"Product"])
    {
        self.parserProduct = nil;
    }
    else if (self.parserElementValue)
    {
        self.parserElementValue = nil;
    }
}

- (void)parserDidEndDocument:(NSXMLParser *)parser
{
    // all done, do whatever you want, just as reloadData for your table

    NSLog(@"%s categories = %@", __FUNCTION__, self.categories);
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
    NSLog(@"%s error=%@", __FUNCTION__, parseError);
}

然后{{1}}方法可能如下:

{{1}}