解析 XML 项目“类别”使用 NSDictionary 转换为 NSArray

发布于 2024-11-03 15:51:44 字数 3242 浏览 4 评论 0原文

问题:

从 .XSD 模板生成的 XML 文件会产生下面粘贴的输出。由于 category 的键是 image,这是我解析 image 的标准方法项目不适用于类别。我想将 category name="Category #" 放入一个数组中,如何从类别字段中创建一个数组。

我需要什么:

我想要的是一系列字典。每个位置都包含一个代表一个类别的字典,每个字典都包含该类别的图像。

数组:@"类别 1",@"类别 2",@"类别 3";

对于每个数组,都有一个包含以下内容的字典:以及之间的所有内容

基本上,我需要从 XML 数据源创建一个如下图所示的 plist

在此处输入图像描述

XML 输出:

<?xml version="1.0" encoding="UTF-8"?>
<app xmlns="http://www.wrightscs.com/_xml_.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.wrightscs.com/_xml_.xsd" name="Testing" unlock_product_id="com.wrightscs.all">
    <bannerImg>http://www.wrightscs.com</bannerImg> 
    <category name="Category 1" icon="http://www.wrightscs.com">
        <image>
                <title>title</title>
                <thumbUrl>http://www.wrightscs.com</thumbUrl>
                <sampleUrl>http://www.wrightscs.com</sampleUrl>
                <imageUrl>http://www.wrightscs.com</imageUrl>
                <description>These items / keys not an issue.</description>
                <infoUrl>http://www.wrightscs.com</infoUrl>
                <license>http://www.wrightscs.com</license>
                <licenseUrl>http://www.wrightscs.com</licenseUrl>
        </image>
    </category>
    <category name="Category 2" icon="http://www.wrightscs.com">
        <image>
                <title>title</title>
                <thumbUrl>http://www.wrightscs.com</thumbUrl>
                <sampleUrl>http://www.wrightscs.com</sampleUrl>
                <imageUrl>http://www.wrightscs.com</imageUrl>
                <description>These items / keys not an issue.</description>
                <infoUrl>http://www.wrightscs.com</infoUrl>
                <license>http://www.wrightscs.com</license>
                <licenseUrl>http://www.wrightscs.com</licenseUrl>
        </image>
    </category> 
    <category name="Category 3" icon="http://www.wrightscs.com">
        <image>
                <title>title</title>
                <thumbUrl>http://www.wrightscs.com</thumbUrl>
                <sampleUrl>http://www.wrightscs.com</sampleUrl>
                <imageUrl>http://www.wrightscs.com</imageUrl>
                <description>These items / keys not an issue.</description>
                <infoUrl>http://www.wrightscs.com</infoUrl>
                <license>http://www.wrightscs.com</license>
                <licenseUrl>http://www.wrightscs.com</licenseUrl>
        </image>
    </category>
</app>

注意:没有其他项目/ 键是一个问题,我只对将类别放入数组感兴趣。此示例中的 URL 也替换为原始内容。

Question:

The generated XML file from an .XSD template produces the output pasted below. Since category's keys are image, my standard way of parsing the image items wont work on category. I would like to place the category name="Category #" into an array, How can I make an array from the category fields.

What I need:

What I want is an array of dictionaries. Each position contains a dictionary representing one category, and each dictionary contains images for that category.

Array: @"Category 1",@"Category 2",@"Category 3";

For each Array, a Dictionary with: <image>and everything in between</image>

Basically, I need to create a plist like the following image, from the XML data source

enter image description here

XML Output:

<?xml version="1.0" encoding="UTF-8"?>
<app xmlns="http://www.wrightscs.com/_xml_.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.wrightscs.com/_xml_.xsd" name="Testing" unlock_product_id="com.wrightscs.all">
    <bannerImg>http://www.wrightscs.com</bannerImg> 
    <category name="Category 1" icon="http://www.wrightscs.com">
        <image>
                <title>title</title>
                <thumbUrl>http://www.wrightscs.com</thumbUrl>
                <sampleUrl>http://www.wrightscs.com</sampleUrl>
                <imageUrl>http://www.wrightscs.com</imageUrl>
                <description>These items / keys not an issue.</description>
                <infoUrl>http://www.wrightscs.com</infoUrl>
                <license>http://www.wrightscs.com</license>
                <licenseUrl>http://www.wrightscs.com</licenseUrl>
        </image>
    </category>
    <category name="Category 2" icon="http://www.wrightscs.com">
        <image>
                <title>title</title>
                <thumbUrl>http://www.wrightscs.com</thumbUrl>
                <sampleUrl>http://www.wrightscs.com</sampleUrl>
                <imageUrl>http://www.wrightscs.com</imageUrl>
                <description>These items / keys not an issue.</description>
                <infoUrl>http://www.wrightscs.com</infoUrl>
                <license>http://www.wrightscs.com</license>
                <licenseUrl>http://www.wrightscs.com</licenseUrl>
        </image>
    </category> 
    <category name="Category 3" icon="http://www.wrightscs.com">
        <image>
                <title>title</title>
                <thumbUrl>http://www.wrightscs.com</thumbUrl>
                <sampleUrl>http://www.wrightscs.com</sampleUrl>
                <imageUrl>http://www.wrightscs.com</imageUrl>
                <description>These items / keys not an issue.</description>
                <infoUrl>http://www.wrightscs.com</infoUrl>
                <license>http://www.wrightscs.com</license>
                <licenseUrl>http://www.wrightscs.com</licenseUrl>
        </image>
    </category>
</app>

Note: none of the other items / keys are an issue, I am only interested in making category into an array. The URL's in this example are also replaced from the original content.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

北方的巷 2024-11-10 15:51:44

看看 xpath 和这个: http: //blog.objectgraph.com/index.php/2010/02/24/parsing-html-iphone-development/

在这种情况下,您需要的 xpath 是

//category/@name

这与上面提到的库应该返回数组中的类别名称。

有关更多 xpath 语法,请检查: http://www.w3schools.com/xpath/default.asp

take a look to xpath and this: http://blog.objectgraph.com/index.php/2010/02/24/parsing-html-iphone-development/

in this case the xpath you need is

//category/@name

this with the library mentioned above should return the categories names in a array.

for more xpath syntax, check this: http://www.w3schools.com/xpath/default.asp

分开我的手 2024-11-10 15:51:44

解决方案:

#pragma mark -
#pragma mark Delegate Received

-(void)parsingComplete:(XMLDataSource*)theParser {
    NSArray *categoryArray = [theParser getCategories];
    [categoryArray writeToFile:PLIST atomically:YES];
}
- (void)receivedItems:(NSArray *)theItems {
    NSMutableArray *dataItems = [[NSMutableArray alloc] init];
    [dataItems addObjectsFromArray:[NSArray arrayWithContentsOfFile:PLIST]];

    NSDictionary * dataItem = [dataItems objectAtIndex:categoryIndex];
    data_ =  [dataItem objectForKey:@"images"];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"updateThumbs" object:nil];
}


#pragma mark -
#pragma mark Parsing Delegates

- (void)parse:(NSData *)data withDelegate:(id)sender onComplete:(SEL)callback 
{
    parentDelegate = sender;
    onCompleteCallback = callback;
    loading = YES;

    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    [parser setDelegate:self];
    [parser setShouldProcessNamespaces:NO];
    [parser setShouldReportNamespacePrefixes:NO];
    [parser setShouldResolveExternalEntities:NO];
    [parser parse];
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    parsed = NO;
    loading = NO;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 
{
    NSString *element = [elementName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    currentElement = element;
    if ([[currentElement lowercaseString] isEqual:@"image"]) {
        inImage = YES;
        itemsDictionary = [[NSMutableDictionary alloc] init];
        [itemsDictionary addEntriesFromDictionary:attributeDict];
    }

    if ([[currentElement lowercaseString] isEqual:@"category"]) {
        inCategory = YES;
        categoryDictionary = [[NSMutableDictionary alloc] init];
        [categoryDictionary addEntriesFromDictionary:attributeDict];
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName 
{
    NSString *element = [elementName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    if ([[element lowercaseString] isEqual:@"image"]) {
        inImage = NO;
        [items addObject:[itemsDictionary copy]];
    }

    if ([[element lowercaseString] isEqual:@"category"]) {
        inCategory = NO;
        [categoryDictionary setObject:[items copy] forKey:@"images"];
        [items removeAllObjects];
        [categories addObject:[categoryDictionary copy]];
    }
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{
    NSString *stringValue = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    NSString *element = [currentElement stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

    /*  skip over blank elements.  */
    if (stringValue == nil || [stringValue isEqual:@""]) {
        return;
    }

    if (element != nil && [element length] > 0) {
        if (inImage) {
            if ([itemsDictionary objectForKey:element] != nil) {
                [itemsDictionary setObject:[NSString stringWithFormat:@"%@%@", [itemsDictionary objectForKey:element], stringValue]
                                    forKey:element];
            } else {
                [itemsDictionary setObject:stringValue forKey:element];
            }
        } else if ((!inImage) && (inCategory)) {
            if ([categoryDictionary objectForKey:element] != nil) {
                [categoryDictionary setObject:[NSString stringWithFormat:@"%@%@", [categoryDictionary objectForKey:element], stringValue]
                                       forKey:element];
            } else {
                [categoryDictionary setObject:stringValue forKey:element];
            }
        } else {
            if ([root objectForKey:element] != nil) {
                [root setObject:stringValue forKey:element];
            }
        }
    }
}
- (void)parserDidStartDocument:(NSXMLParser *)parser {
    NSError * err;
    if(![[NSFileManager defaultManager] fileExistsAtPath:PLIST]) {
        [[NSFileManager defaultManager] removeItemAtPath:PLIST error:&err];
    }
}
- (void)parserDidEndDocument:(NSXMLParser *)parser 
{
    parsed = YES;
    loading = NO;

    if ([parentDelegate respondsToSelector:onCompleteCallback]) {
        [parentDelegate performSelector:onCompleteCallback withObject:self];
    }

    if ([self respondsToSelector:@selector(receivedItems:)])
        [self receivedItems:items];
    else
        SHOW_ALERT(@"parserDidEndDocument:", @"receivedItems: not responding!", nil, @"Okay", nil)
}


#pragma mark -
#pragma mark Setters / Getters

- (id)delegate {
    return self;
}
- (void)setDelegate:(id)new_delegate {
    _delegate = self;
}
- (BOOL)isSuccessful {
    return success;
}
- (BOOL)isLoading {
    return loading;
}
- (BOOL)isParsed {
    return parsed;
}
- (NSArray *)getCategories {
    return categories;
}
- (NSDictionary *)getRoot {
    return root;
}
- (void)dealloc {
    [super dealloc];
}

The Solution:

#pragma mark -
#pragma mark Delegate Received

-(void)parsingComplete:(XMLDataSource*)theParser {
    NSArray *categoryArray = [theParser getCategories];
    [categoryArray writeToFile:PLIST atomically:YES];
}
- (void)receivedItems:(NSArray *)theItems {
    NSMutableArray *dataItems = [[NSMutableArray alloc] init];
    [dataItems addObjectsFromArray:[NSArray arrayWithContentsOfFile:PLIST]];

    NSDictionary * dataItem = [dataItems objectAtIndex:categoryIndex];
    data_ =  [dataItem objectForKey:@"images"];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"updateThumbs" object:nil];
}


#pragma mark -
#pragma mark Parsing Delegates

- (void)parse:(NSData *)data withDelegate:(id)sender onComplete:(SEL)callback 
{
    parentDelegate = sender;
    onCompleteCallback = callback;
    loading = YES;

    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    [parser setDelegate:self];
    [parser setShouldProcessNamespaces:NO];
    [parser setShouldReportNamespacePrefixes:NO];
    [parser setShouldResolveExternalEntities:NO];
    [parser parse];
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    parsed = NO;
    loading = NO;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 
{
    NSString *element = [elementName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    currentElement = element;
    if ([[currentElement lowercaseString] isEqual:@"image"]) {
        inImage = YES;
        itemsDictionary = [[NSMutableDictionary alloc] init];
        [itemsDictionary addEntriesFromDictionary:attributeDict];
    }

    if ([[currentElement lowercaseString] isEqual:@"category"]) {
        inCategory = YES;
        categoryDictionary = [[NSMutableDictionary alloc] init];
        [categoryDictionary addEntriesFromDictionary:attributeDict];
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName 
{
    NSString *element = [elementName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    if ([[element lowercaseString] isEqual:@"image"]) {
        inImage = NO;
        [items addObject:[itemsDictionary copy]];
    }

    if ([[element lowercaseString] isEqual:@"category"]) {
        inCategory = NO;
        [categoryDictionary setObject:[items copy] forKey:@"images"];
        [items removeAllObjects];
        [categories addObject:[categoryDictionary copy]];
    }
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{
    NSString *stringValue = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    NSString *element = [currentElement stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

    /*  skip over blank elements.  */
    if (stringValue == nil || [stringValue isEqual:@""]) {
        return;
    }

    if (element != nil && [element length] > 0) {
        if (inImage) {
            if ([itemsDictionary objectForKey:element] != nil) {
                [itemsDictionary setObject:[NSString stringWithFormat:@"%@%@", [itemsDictionary objectForKey:element], stringValue]
                                    forKey:element];
            } else {
                [itemsDictionary setObject:stringValue forKey:element];
            }
        } else if ((!inImage) && (inCategory)) {
            if ([categoryDictionary objectForKey:element] != nil) {
                [categoryDictionary setObject:[NSString stringWithFormat:@"%@%@", [categoryDictionary objectForKey:element], stringValue]
                                       forKey:element];
            } else {
                [categoryDictionary setObject:stringValue forKey:element];
            }
        } else {
            if ([root objectForKey:element] != nil) {
                [root setObject:stringValue forKey:element];
            }
        }
    }
}
- (void)parserDidStartDocument:(NSXMLParser *)parser {
    NSError * err;
    if(![[NSFileManager defaultManager] fileExistsAtPath:PLIST]) {
        [[NSFileManager defaultManager] removeItemAtPath:PLIST error:&err];
    }
}
- (void)parserDidEndDocument:(NSXMLParser *)parser 
{
    parsed = YES;
    loading = NO;

    if ([parentDelegate respondsToSelector:onCompleteCallback]) {
        [parentDelegate performSelector:onCompleteCallback withObject:self];
    }

    if ([self respondsToSelector:@selector(receivedItems:)])
        [self receivedItems:items];
    else
        SHOW_ALERT(@"parserDidEndDocument:", @"receivedItems: not responding!", nil, @"Okay", nil)
}


#pragma mark -
#pragma mark Setters / Getters

- (id)delegate {
    return self;
}
- (void)setDelegate:(id)new_delegate {
    _delegate = self;
}
- (BOOL)isSuccessful {
    return success;
}
- (BOOL)isLoading {
    return loading;
}
- (BOOL)isParsed {
    return parsed;
}
- (NSArray *)getCategories {
    return categories;
}
- (NSDictionary *)getRoot {
    return root;
}
- (void)dealloc {
    [super dealloc];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文