我目前正在开发一个用于显示一些信息的iOS应用程序(目标= iPod touch),这些信息基于PostgreSQL数据库而且我是一个非常初学者。我做了很多研究,但我什么也没找到,这对解决我的问题非常有帮助。
目前我从php文件中获取数据,这是iOS App和数据库之间的“桥梁”。为此,我使用http请求向php文件询问xml格式的数据。在php文件中我使用
SELECT query_to_xml('".$queryString."', false, true, '') as xml
获取一个xml文件作为回报。
到目前为止一切正常,所以我有一个字符串变量,其中包含我的iOS应用程序中可用查询的xml结果。
这就是我得到的:
<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<id>4</id>
<invnr>61821B741AEBI8</invnr>
<art>c</art>
<type_id>2</type_id>
<rechnung></rechnung>
<standort>G01E01R01</standort>
<erstellt>2011-12-06</erstellt>
<gekauft>2003-01-01</gekauft>
</row>
在objective-c中我希望有两个数组:
字幕数组
第一个数组应该保存xml文件中的标题(id,invnr,art,type_id,rechnung,standort,erstellt,gekauft)。条目“row”不应该在数组中。
值数组
第二个数组应该只保存值 - 也是空值。在那个例子中它将是4,61821B741AEBI8,c,2,G01E01R01,2011-12-06,2003-01-01
使用NSXML Parser
这是配置,我目前用它来解析xml并将数据保存到数组中。
Parser didStartElement
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict{
element = [[NSMutableString alloc] init];
if(!dataCaptions){
dataCaptions = [[NSMutableArray alloc]init];
}
if([elementName isEqualToString:@"id"] ||
[elementName isEqualToString:@"invnr"] ||
[elementName isEqualToString:@"art"] ||
[elementName isEqualToString:@"type_id"] ||
[elementName isEqualToString:@"rechnung"] ||
[elementName isEqualToString:@"standort"] ||
[elementName isEqualToString:@"erstellt"] ||
[elementName isEqualToString:@"gekauft"]){
[element setString:elementName];
[dataCaptions addObject:elementName];
}
}
Parser foundCharacters
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if(!dataValues){
dataValues = [[NSMutableArray alloc]init];
}
BOOL copy;
if([element isEqualToString:@"id"] ||
[element isEqualToString:@"invnr"] ||
[element isEqualToString:@"art"] ||
[element isEqualToString:@"type_id"] ||
[element isEqualToString:@"rechnung"]||
[element isEqualToString:@"standort"] ||
[element isEqualToString:@"erstellt"] ||
[element isEqualToString:@"gekauft"]){
copy = YES;
}else{
copy = NO;
}
if(copy){
[dataValues addObject:string];
NSLog(@"Found: %@ with value: %@", element, string);
}
}
Parser didEndElement
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName{
}
输出和问题
问题是解析器似乎多次通过一个元素。这导致我的值数组看起来像:
2013-03-14 12:54:54.591 BarcodeScanner[582:907] Array Values(
4,
"\n ",
61821B741AEBI8,
"\n ",
c,
"\n ",
2,
"\n ",
"\n ",
G01E01R01,
"\n ",
"2011-12-06",
"\n ",
"2003-01-01",
"\n"
)
输出也有点复杂。我的错误是解析器首先采用起始xml标签,例如。 (Parser didStartElement),比读取值4(Parser foundCharacters)并且至少读取(Parser didEndElement)?
我希望有人可以帮助解决这个问题。 谢谢和最好的问候 - 托比亚斯
2013-03-14 12:54:54.423 BarcodeScanner[582:907] Found: id with value: 4
2013-03-14 12:54:54.425 BarcodeScanner[582:907] Found: id with value:
2013-03-14 12:54:54.426 BarcodeScanner[582:907] Found: invnr with value: 61821B741AEBI8
2013-03-14 12:54:54.428 BarcodeScanner[582:907] Found: invnr with value:
2013-03-14 12:54:54.430 BarcodeScanner[582:907] Found: art with value: c
2013-03-14 12:54:54.432 BarcodeScanner[582:907] Found: art with value:
2013-03-14 12:54:54.444 BarcodeScanner[582:907] Found: type_id with value: 2
2013-03-14 12:54:54.446 BarcodeScanner[582:907] Found: type_id with value:
2013-03-14 12:54:54.448 BarcodeScanner[582:907] Found: rechnung with value:
2013-03-14 12:54:54.450 BarcodeScanner[582:907] Found: standort with value: G01E01R01
2013-03-14 12:54:54.451 BarcodeScanner[582:907] Found: standort with value:
2013-03-14 12:54:54.454 BarcodeScanner[582:907] Found: erstellt with value: 2011-12-06
2013-03-14 12:54:54.456 BarcodeScanner[582:907] Found: erstellt with value:
2013-03-14 12:54:54.461 BarcodeScanner[582:907] Found: gekauft with value: 2003-01-01
2013-03-14 12:54:54.464 BarcodeScanner[582:907] Found: gekauft with value:
答案 0 :(得分:0)
您是正确的,您需要实施didStartElement
,foundCharacters
和didEndElement
。您在处理给定元素的过程中将多次调用foundCharacters
也是正确的,因此您需要通过将字符附加到字符串来处理此问题,而不是创建一个每次都是新的独立字符串。或者,正如Apple将其置于docs:
解析器对象可以发送几个委托 parser:foundCharacters:报告一个字符的消息 元件。因为字符串可能只是整个字符的一部分 当前元素的内容,您应该将其附加到当前元素 字符的积累直到元素改变。
作为一个例子,这是我从当前项目中完整实现的一个简单的工作解析器。请注意foundCharacters
是多么简单 - 在基本级别需要做的就是在调用didEndElement
之前将字符附加到字符串中(然后您可以在didEndElement
中清除它并启动再次附加过程):
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict{
if([elementName isEqualToString:@"device"]){
self.currentDeviceID = [[SRDeviceID alloc]init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if([elementName isEqualToString:@"deviceList"]){
[self.pairingTableView reloadData];
}
if([elementName isEqualToString:@"device"]){
[self.deviceIDListFromServer addObject:self.currentDeviceID];
}
//The accumulation of characters for the current element is complete,
//so we can tidy up the string and use the result:
NSString* finalParsedString = [self.currentParseString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if([elementName isEqualToString:@"deviceName"]){
self.currentDeviceID.deviceName = finalParsedString;
}
if([elementName isEqualToString:@"UUID"]){
self.currentDeviceID.uuid = finalParsedString;
}
if([elementName isEqualToString:@"deviceLocation"]){
self.currentDeviceID.location = finalParsedString;
}
if([elementName isEqualToString:@"deviceLastSeenTime"]){
self.currentDeviceID.lastSeenTime = finalParsedString;
}
//Now we've used the accumulated string from the current element,
//we can clear it ready to start the accumulation process for
//the next element's contents:
self.currentParseString = [NSMutableString stringWithString:@""];
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
//All we need to do here is add the next lot of characters
//to the accumulating string for the current element,
//which continues to happen until didEndElement is called:
[self.currentParseString appendString:string];
}