0

各製品がカテゴリに属する​​製品カタログを表す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>

データを格納するクラスを作成し、インスタンスを配列に配置しました。*次に、それをテーブルビューに表示します。現在、テーブルビューにはItem_numbersのリストが表示されます:D

私が達成しようとしていることは同じですが、2ページにしたいです。繰り返しのない(一意の)カテゴリ(ABC、XYZなど)を含むメインテーブルビュー。2ページ目-詳細テーブルビューには、選択したカテゴリに属する​​item_numberが表示されます。このような ..

メインテーブルビュー:

ABC >
XYZ >

詳細テーブルビュー(「ABC」を選択):

123
456

(1)これに対する最善のアプローチは何ですか?

(2)私の最初の障害は、カテゴリ「ABC」から値を解析することだと思います

    <Product category="ABC">

私の実装では、単に呼び出すと空白になります(XMLにカテゴリがある場合に値を解析するのは少し異なります)

cell.textLabel.text = product.product;

(3)2つ目は、データを保存する方法(または同じアプローチを維持する方法*)です。1ページ目から1つのカテゴリを選択すると、詳細なテーブルビューページを参照できます。


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取得されます。didStartElementattributeselementName@"Product"

「最善のアプローチ」に関しては、データ構造を決定するだけです。カテゴリディクショナリエントリの配列であるNSMutableArrayを作成することをお勧めします。これは、カテゴリごとに1つであり、ディクショナリ内のオブジェクトの1つは、そのカテゴリ内の製品の配列になります。

その構造ができたら、3番目の質問に答えることはおそらく明白です。


まず、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>

次に、カテゴリの配列が必要であり、カテゴリごとに製品の配列が必要であると仮定すると、実装は次のようになります。まず、いくつかのプロパティが必要です。1つは最終結果用で、もう2つは解析中に使用される一時変数用です。

// 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 に答える