1

我一直试图弄清楚这一点,但无法解决。希望这里的人会有一个想法。

我有一些我正在解析的 XML 数据,它看起来像:

    <Name>MAC 101</Name>
    <Modes>
        <Mode>
            <Name>Basic RGB</Name>
            <ChannelCount>8</ChannelCount>
        </Mode>
        <Mode>
            <Name>Raw RGB</Name>
            <ChannelCount>12</ChannelCount>
        </Mode>
    </Modes>

我正在做的是将信息保存到 SQLite 数据库,但是我需要先将一些信息组合成 1 个字符串。我需要字符串看起来像:(带换行符)

8 基本 RGB
12 原始 RGB

然而,有时会有多个“模式”,这个例子只有 2 个,有时可能有十几个或更多。

我正在使用的当前代码是 NSXMLParser:

-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if (isStatus) {
    if ([elementName isEqualToString:@"Name"]) {
        CurrentFixture.Title = currentNodeContent;
        NSLog(@"Name: %@",currentNodeContent);
    }
    if ([elementName isEqualToString:@"Name"]) {
        CurrentFixture.ModeName = currentNodeContent;
        NSLog(@"Mode Name: %@",currentNodeContent);
    }
    if ([elementName isEqualToString:@"ChannelCount"]) {
        CurrentFixture.ChannelCount = currentNodeContent;
        NSLog(@"Channel Count: %@",currentNodeContent);
    }
}
 if ([elementName isEqualToString:@"Fixture"]) {
    NSLog(@"Do something with data.");
    [self.data addObject:CurrentFixture];
    NSLog(@"Data: %@",);
    CurrentFixture = nil;
    currentNodeContent = nil;
    }
}

模式名称将更改标签,因此它不会与实际名称混淆,但目前我只需要让一些工作正常。任何建议或指导将不胜感激。谢谢安德鲁

4

2 回答 2

0

你需要

  • 一个数组来跟踪你的所有模式,例如modesArray

  • 一个对象字典来跟踪你的模式'ChannelCountName,例如modeDictionary; 和

  • 和一些BOOL变量,这样你就知道你是否正在解析你的模式数组(最重要的是,你可以区分NameaMode和更高级别Name,例如parsingModes.

那么你可以,

  • 当你启动一个模式时,初始化你的数组;

  • 当你启动 aMode时,初始化字典;

  • 当你完成一个NameorChannelCount时,更新模式字典;

  • 当您完成 aMode时,您可以将这两个值连接成一个字符串,并将该字符串添加到您的数组中;

  • 完成 后,您可以使用换行符连接数组Modes中的所有这些字符串。Mode

从而产生类似:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if ([elementName isEqualToString:@"Fixture"])
    {
        currentFixture = [[Fixture alloc] init];
    }
    else if ([elementName isEqualToString:@"Modes"])
    {
        modesArray = [NSMutableArray array];
        parsingModes = YES;
    }
    else if ([elementName isEqualToString:@"Mode"])
    {
        modeDictionary = [NSMutableDictionary dictionary];
    }
    else
    {
        currentNodeContent = [NSMutableString string];
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    [currentNodeContent appendString:string];
}

-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if (parsingModes)
    {
        if ([elementName isEqualToString:@"Name"]) {
            modeDictionary[@"Name"] = currentNodeContent;
        }
        else if ([elementName isEqualToString:@"ChannelCount"]) {
            modeDictionary[@"ChannelCount"] = currentNodeContent;
        }
        else if ([elementName isEqualToString:@"Mode"]) {
            [modesArray addObject:[NSString stringWithFormat:@"%@ %@", modeDictionary[@"ChannelCount"], modeDictionary[@"Name"]]];
            modeDictionary = nil;
        }
        else if ([elementName isEqualToString:@"Modes"]) {
            currentFixture.longStringWithModes = [modesArray componentsJoinedByString:@"\n"];
            modesArray = nil;
            parsingModes = NO;
        }
    }
    else
    {
        if ([elementName isEqualToString:@"Name"]) {
            currentFixture.title = currentNodeContent;
        }
    }

    // carry on with your other elements

    currentNodeContent = nil;
}

(注意我改用驼峰式了。)

在向您展示了如何执行此操作后,我建议您不要这样做。数据库最好将数据保存在单独的字段中。将所有内容连接成单个字符串可能是您在 UI 中执行的操作,但数据库可能应该反映底层数据结构。话虽如此,由于每个灯具都有多个Mode条目,这意味着您可能会有一个单独的表格。

于 2013-09-07T13:56:31.690 回答
0

完成所有解析后,您将需要一个函数。看起来你没有给我们整个 XML 文件,但我假设你的外部标签是<Fixtures>,你的内部标签是<Fixture>. 放弃这个假设,您可以添加签入parser:didEndElement:

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

    if ([elementName isEqualToString:@"Fixtures"]) {
        [self saveModesToDatabase];
    }
}

-(void) saveModesToDatabase {
    NSString* allModes = @"";
    for (Fixture* aFixture in self.data) {
        NSString* modeString = [aFixture.ChannelCount stringByAppendingFormat:@" %@", aFixture.Title];

        // Don't add a line break if it's the last object
        if (aFixture == [self.data lastObject])
            allModes = [allModes stringByAppendingFormat:@"%@", modeString];
        else
            allModes = [allModes stringByAppendingFormat:@"%@\n", modeString];
    }

    // Save allModes to database
}
于 2013-09-07T13:26:51.623 回答