Cocoa-Touch/iPhone中的XML解析
好的,我看过TouchXML、parseXML、NSXMLDocument、NSXMLParser,但我真的不知道该怎么做 我有一个iphone应用程序,它连接到服务器,请求数据并获得XML响应。下面给出了对不同查询集的示例xml响应 我有另一个类作为控制器(在MVC中,用于获取数据的逻辑)。该类从视图类获取输入并对其进行处理,例如,向Web服务器发送请求、获取xml、解析xml、填充其变量(它是一个单例/共享类),然后以true或false响应调用者。调用者根据控制器类给出的响应,检查控制器的变量并向用户显示适当的内容 我有以下控制器类变量:Cocoa-Touch/iPhone中的XML解析,iphone,xml,cocoa-touch,Iphone,Xml,Cocoa Touch,好的,我看过TouchXML、parseXML、NSXMLDocument、NSXMLParser,但我真的不知道该怎么做 我有一个iphone应用程序,它连接到服务器,请求数据并获得XML响应。下面给出了对不同查询集的示例xml响应 我有另一个类作为控制器(在MVC中,用于获取数据的逻辑)。该类从视图类获取输入并对其进行处理,例如,向Web服务器发送请求、获取xml、解析xml、填充其变量(它是一个单例/共享类),然后以true或false响应调用者。调用者根据控制器类给出的响应,检查控制器的
@interface backendController : NSObject {
NSMutableDictionary *searchResults, *plantInfoResults, *bookmarkList, *userLoginResult;
}
以及getBookmarkList、getPlantInfo等函数。现在,我正在打印Web服务器返回的纯XML
NSLog(@“结果::%@”[NSString stringWithContentsOfURL:url])
我想要一个通用函数,它获取从服务器返回的XML,对其进行解析,生成一个NSMutableDictionary,其中包含XML开始标记的文本表示作为键,XML标记值作为值,并返回该值
只有一个问题,如何做到这一点?您是否尝试过您提到的任何XML解析器?这是它们设置节点名称键值的方式:
[aBook setValue:currentElementValue forKey:elementName];
另外,再次检查XML,似乎在某些结果中缺少根节点。除非你为了简单而省略了它
看一看,它应该为您指明了XML语法的正确方向。考虑以下代码段,它使用和来解析HTTP文档 要解析XML,请使用
PerformXMLXPathQuery
而不是我在示例中使用的PerformHTTPXPathQuery
类型为NSArray*
的节点
实例将包含NSDictionary*
对象,您可以递归解析这些对象以获取所需的数据
或者,如果您知道XML文档的模式,那么可以编写XPath查询,直接获取nodeContent
或nodeAttribute
值
ASIHTTPRequest *request = [ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://stackoverflow.com/"];
[request start];
NSError *error = [request error];
if (!error) {
NSData *response = [request responseData];
NSLog(@"Root node: %@", [[self query:@"//" withResponse:response] description]);
}
else
@throw [NSException exceptionWithName:@"kHTTPRequestFailed" reason:@"Request failed!" userInfo:nil];
[request release];
...
- (id) query:(NSString *)xpathQuery withResponse:(NSData *)respData {
NSArray *nodes = PerformHTMLXPathQuery(respData, xpathQuery);
if (nodes != nil)
return nodes;
return nil;
}
为您提供一个解析表中XML的简单示例,希望对您有所帮助 //XMLViewController.h
#import <UIKit/UIKit.h>
@interface TestXMLViewController : UIViewController<NSXMLParserDelegate,UITableViewDelegate,UITableViewDataSource>{
@private
NSXMLParser *xmlParser;
NSInteger depth;
NSMutableString *currentName;
NSString *currentElement;
NSMutableArray *data;
}
@property (nonatomic, strong) IBOutlet UITableView *tableView;
-(void)start;
@end
#导入
@接口TestXMLViewController:UIViewController{
@私人的
NSXMLParser*xmlParser;
NSInteger深度;
NSMutableString*当前名称;
NSString*currentElement;
NSMutableArray*数据;
}
@属性(非原子,强)IBUITableView*tableView;
-(无效)开始;
@结束
//TestXMLViewController.m
#import "TestXmlDetail.h"
#import "TestXMLViewController.h"
@interface TestXMLViewController ()
- (void)showCurrentDepth;
@end
@implementation TestXMLViewController
@synthesize tableView;
- (void)start
{
NSString *xml = @"<?xml version=\"1.0\" encoding=\"UTF-8\" ?><Node><name>Main</name><Node><name>first row</name></Node><Node><name>second row</name></Node><Node><name>third row</name></Node></Node>";
xmlParser = [[NSXMLParser alloc] initWithData:[xml dataUsingEncoding:NSUTF8StringEncoding]];
[xmlParser setDelegate:self];
[xmlParser setShouldProcessNamespaces:NO];
[xmlParser setShouldReportNamespacePrefixes:NO];
[xmlParser setShouldResolveExternalEntities:NO];
[xmlParser parse];
}
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
NSLog(@"Document started");
depth = 0;
currentElement = nil;
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
NSLog(@"Error: %@", [parseError localizedDescription]);
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
currentElement = [elementName copy];
if ([currentElement isEqualToString:@"Node"])
{
++depth;
[self showCurrentDepth];
}
else if ([currentElement isEqualToString:@"name"])
{
currentName = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:@"Node"])
{
--depth;
[self showCurrentDepth];
}
else if ([elementName isEqualToString:@"name"])
{
if (depth == 1)
{
NSLog(@"Outer name tag: %@", currentName);
}
else
{
NSLog(@"Inner name tag: %@", currentName);
[data addObject:currentName];
}
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([currentElement isEqualToString:@"name"])
{
[currentName appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(@"Document finished", nil);
}
- (void)showCurrentDepth
{
NSLog(@"Current depth: %d", depth);
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
data = [[NSMutableArray alloc]init ];
[self start];
self.title=@"XML parsing";
NSLog(@"string is %@",data);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
`enter code here`return [data count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [data objectAtIndex:indexPath.row];
return cell;
}
@end
#导入“TestXmlDetail.h”
#导入“TestXMLViewController.h”
@接口TestXMLViewController()
-(空)显示当前深度;
@结束
@TestXMLViewController的实现
@综合桌面视图;
-(无效)开始
{
NSString*xml=@“第一行第二行第三行”;
xmlParser=[[NSXMLParser alloc]initWithData:[xml数据使用编码:NSUTF8StringEncoding]];
[xmlParser setDelegate:self];
[xmlParser setShouldProcessNamespaces:否];
[xmlParser setShouldReportNamespacePrefixes:否];
[xmlParser setShouldResolveExternalEntities:否];
[xmlParser parse];
}
-(void)parserdistartdocument:(NSXMLParser*)解析器
{
NSLog(@“文件已启动”);
深度=0;
currentElement=零;
}
-(void)解析器:(NSXMLParser*)解析器解析错误发生:(NSError*)解析错误
{
NSLog(@“错误:%@,[parseError localizedDescription]);
}
-(void)parser:(NSXMLParser*)parser didStartElement:(NSString*)elementName
namespaceURI:(NSString*)namespaceURI
限定名称:(NSString*)qName
属性:(NSDictionary*)属性指令
{
currentElement=[elementName copy];
if([currentElement IsequalString:@“Node”])
{
++深度;
[自显示电流深度];
}
else if([currentElement IsequalString:@“name”])
{
currentName=[[NSMutableString alloc]init];
}
}
-(void)parser:(NSXMLParser*)parser didEndElement:(NSString*)elementName
namespaceURI:(NSString*)namespaceURI
限定名称:(NSString*)qName
{
if([elementName IsequalString:@“Node”])
{
--深度;
[自显示电流深度];
}
else if([elementName IsequalString:@“name”])
{
如果(深度==1)
{
NSLog(@“外部名称标签:%@”,当前名称);
}
其他的
{
NSLog(@“内部名称标签:%@”,currentName);
[数据添加对象:currentName];
}
}
}
-(void)解析器:(NSXMLParser*)解析器查找字符:(NSString*)字符串
{
if([currentElement IsequalString:@“name”])
{
[currentName appendString:string];
}
}
-(void)parserDidEndDocument:(NSXMLParser*)解析器
{
NSLog(@“文件完成”,无);
}
-(无效)显示当前深度
{
NSLog(@“当前深度:%d”,深度);
}
-(无效)viewDidLoad
{
[超级视图下载];
//加载视图后,通常从nib执行任何其他设置。
数据=[[NSMutableArray alloc]init];
[自启动];
self.title=@“XML解析”;
NSLog(@“字符串为%@”,数据);
}
-(NSInteger)表视图:(UITableView*)表视图行数节:(NSInteger)节
{
`在此处输入代码`返回[数据计数];
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
静态NSString*simpleTableIdentifier=@“单元格”;
UITableViewCell*单元格=[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
如果(单元格==nil){
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault重用标识符:simpleTableIdentifier];
}
cell.textlab.text=[data objectAtIndex:indexath.row];
返回单元;
}
@结束
查看获取书签的结果,您的XML是。。。。。。在XML中,您需要一个节点作为所有条目的父节点:。。。。。。。。。看看w3schools教程,我将添加到答案的链接。好的,我修改了XML,服务器返回的新XML I是:它还包含执行时的错误/警告。我似乎无法使用TouchXML以正常方式解析XML。请帮忙。我想这是因为我在返回的XML的开头得到了4个空行