我一直试图弄清楚这一点,但无法解决这个问题。希望这里有人会有一个想法。
我有一些我正在解析的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;
}
}
模式名称将改变标签,因此它不会与实际名称混淆,但目前我只需要一些工作。 任何建议或指导将不胜感激。 谢谢 安德鲁
答案 0 :(得分: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
}
答案 1 :(得分:0)
你需要
用于跟踪所有模式的数组,例如modesArray
;
用于跟踪您的模式“ChannelCount
和Name
的对象词典,例如modeDictionary
;以及
和一些BOOL
变量让您知道您是否正在解析模式数组(最重要的是,您可以区分Name
中的Mode
和较高级Name
,例如parsingModes
。
然后,您可以
启动模式时,初始化阵列;
当您开始Mode
时,请初始化词典;
完成Name
或ChannelCount
后,请更新模式字典;
完成Mode
后,您可以将这两个值连接成一个字符串,并将该字符串添加到数组中;
完成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;
}
(注意我转移到了camelCase。)
告诉你如何做到这一点,我建议不要这样做。数据库最好将数据保存在单独的字段中。将所有内容连接成单个字符串可能是您在UI中执行的操作,但数据库可能应该反映基础数据结构。话虽如此,由于每个灯具有多个Mode
条目,这意味着您可能有一个单独的表格。