0

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

<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

我想要实现的是相同的,但我希望有 2 页。具有非重复(唯一)类别(即 ABC、XYZ)的主表视图,在第二页 - 详细表视图上,它将显示属于所选类别的 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;
        }
    }
4

1 回答 1

0

关于解析category,那是didStartElementattributes字典中检索的 when elementNameis @"Product"

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

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


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

<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;

然后这些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);
}
于 2012-12-14T17:30:12.040 回答