您好,登錄后才能下訂單哦!
SAX逐行解析
SAX:SimpleAPIfor XML。基于事件驅動的解析方式,逐行解析數據。(采用協議回調機制)
NSXMLParser是iOS自帶的XML解析類。采用SAX方式解析數據
解析過程由NSXMLParserDelegate協議方法回調
解析過程:開始標簽->取值->結束標簽->取值
DOM解析
DOM:DocumentObjectModel(文檔對象模型)。解析時需要將XML文件整體讀入,并且將XML結構化成樹狀,使用時再通過樹狀結構讀取相關數據
GDataXMLNode(這個類在下載包里面)是Google提供的開源XML解析類,對libxml2.dylib進行了Objective-C的封裝
采用DOM方式解析數據
iOS中包含一個C語言的動態鏈接庫libxml2.dylib,解析速度比NSXMLParser快
AppDelegate.m #import "AppDelegate.h" #import "MainViewController.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; MainViewController *mainVC = [[MainViewController alloc] init]; UINavigationController *naviVC = [[UINavigationController alloc] initWithRootViewController:mainVC]; self.window.rootViewController = naviVC; [naviVC release]; [mainVC release]; [_window release]; return YES; } - (void)dealloc { [_window release]; [super dealloc]; } - (void)applicationWillResignActive:(UIApplication *)application { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - (void)applicationDidEnterBackground:(UIApplication *)application { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - (void)applicationDidBecomeActive:(UIApplication *)application { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - (void)applicationWillTerminate:(UIApplication *)application { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } @end
MainViewController.m #import "MainViewController.h" #import "XMLSAXParser.h" #import "JSONParser.h" @interface MainViewController () @end @implementation MainViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor cyanColor]; //XML SAX解析(逐行解析) XMLSAXParser *parser = [[XMLSAXParser alloc] init]; [parser startParse]; NSLog(@"解析后的%@",parser.array); [parser release]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } /* #pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } */ @end
XMLSAXParser.h #import <Foundation/Foundation.h> @interface XMLSAXParser : NSObject<NSXMLParserDelegate> @property (nonatomic , retain)NSMutableArray *array; //裝學生對象 @property (nonatomic , retain)NSString *tempStr; //臨時健在節點內容 - (void)startParse; //開始解析,逐行解析 - (void)startDOMParse; //開始dom解析,按節點解析 @end
XMLSAXParser.m #import "XMLSAXParser.h" #import "Student.h" #import "GDataXMLNode.h" @implementation XMLSAXParser //XML解析:逐行解析 - (void)startParse; { //XML解析:逐行解析 //從文件列表中讀取數據 //1.獲取文件路徑 NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"Student" ofType:@"xml"]; //2.通過路徑把文件轉換成NSData類型 NSData *data = [NSData dataWithContentsOfFile:sourcePath]; //創建的時候需要給parser一個字符串數據(NSData) NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; //設定代理人 parser.delegate = self; //開始對文件進行解析 [parser parse]; //內存管理 [parser release]; } - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { //當找到節點頭的時候,體統調用這個方法 NSLog(@"節點頭"); if ([elementName isEqualToString:@"students"]) { //當找到students節點頭的時候,初始化數組 self.array = [NSMutableArray array]; }else if ([elementName isEqualToString:@"student"]){ //當找到student節點時候,創建一個新的學生對象,添加到數組中 Student *stu = [[Student alloc] init]; [self.array addObject:stu]; [stu release]; } } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { //當找到節點內容的時候,調用 NSLog(@"節點內容"); //把內容保存起來,只要碰到節點內容,下一個肯定是節點尾 self.tempStr = string; } - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { //當找到節點尾時候調用 NSLog(@"節點尾"); //取得之前保存的student對象 Student *stu = [self.array lastObject]; //核心代碼,懂了沒 ......... if ([elementName isEqualToString:@"name"]) { stu.name = self.tempStr; }else if ([elementName isEqualToString:@"sex"]){ stu.sex = self.tempStr; }else if ([elementName isEqualToString:@"phone"]){ stu.phone = self.tempStr; }else if ([elementName isEqualToString:@"number"]){ stu.number = self.tempStr; } } //開始dom解析,按節點解析 - (void)startDOMParse { //按節點解析 //1.獲取要解析文件的文件信息 NSString *xmlPath = [[NSBundle mainBundle]pathForResource:@"Student" ofType:@"xml"]; NSData *data = [NSData dataWithContentsOfFile:xmlPath]; //參數1:要解析的xml串 //參數2:隨便 //參數3:錯誤信息 GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil]; //2.獲取文件的根節點 GDataXMLElement *rootElement = [doc rootElement]; //3.進一步搜索所有的子節點 //返回一個裝滿了student節點(GDataXMLElement對象)的數組 NSArray *array = [rootElement elementsForName:@"student"]; self.array = [NSMutableArray array]; //4.遍歷數組,把student節點的每個子節點取出來 for (GDataXMLElement *element in array) { Student *stu = [[Student alloc] init]; GDataXMLElement *nameElement = [[element elementsForName:@"name"]lastObject]; //從name節點中取值 NSString *name = [nameElement stringValue]; //給學生對象的屬性賦值 stu.name = name; //把學生對象添加到數組中-----------其他的雷同 [self.array addObject:stu]; [stu release]; } } @end
Student.h #import <Foundation/Foundation.h> @interface Student : NSObject @property (nonatomic , retain)NSString *number; @property (nonatomic , retain)NSString *name; @property (nonatomic , retain)NSString *sex; @property (nonatomic , copy)NSString *phone; @end
Student.m
#import "Student.h" @implementation Student - (void)dealloc { [_name release]; [_number release]; [_sex release]; [_phone release]; [super dealloc]; } //當這個類的對象被NSLog輸出時候,系統會先調用這個方法,如果這個方法被重寫,就直接輸出重寫的內容,否則就輸出系統默認的內容 - (NSString *)description { return [NSString stringWithFormat:@"name:%@ sex:%@ phone:%@ number:%@", self.name, self.sex, self.phone, self.number]; } @end
這里需要注意的是添加第三方類的步驟:
直接添加第三方類是有錯的
在GDataXMLNode.h中
// libxml includes require that the target Header Search Paths contain
//
// /usr/include/libxml2
//
// and Other Linker Flags contain
//
// -lxml2
在下面的對上面的文件中首先搜索Header Search 然后在第二行中添加上/usr/include/libxml2
然后同理搜索Other Linker然后在第二行中添加上-lxml2
這樣第三方類就可以使用了 .
XML在不同的語言里解析方式都是一樣的,只不過實現的語法不同而已。基本的解析方式有兩種,一種叫SAX,另一種叫DOM。SAX是基于事件流的解析,DOM是基于XML文檔樹結構的解析.假設我們XML的內容和結構如下:
[xhtml] view plaincopy
<?xml version="1.0" encoding="UTF-8"?> <employees> <employee> <name>ddviplinux</name> <sex>m</sex> <age>30</age> </employee> </employees>
下面是解析XMl常用的Dom和Sex方法:
1.DOM生成和解析XML文檔
為 XML 文檔的已解析版本定義了一組接口。解析器讀入整個文檔,然后構建一個駐留內存的樹結構,然后代碼就可以使用 DOM 接口來操作這個樹結構。優點:整個文檔樹在內存中,便于操作;支持刪除、修改、重新排列等多種功能;缺點:將整個文檔調入內存(包括無用的節點),浪費時間和空間;使用場合:一旦解析了文檔還需多次訪問這些數據;硬件資源充足(內存、CPU)。
[java] view plaincopy
public void parserXml(String fileName) { try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document document = db.parse(fileName); NodeList employees = document.getChildNodes(); for (int i = 0; i < employees.getLength(); i++) { Node employee = employees.item(i); NodeList employeeInfo = employee.getChildNodes(); for (int j = 0; j < employeeInfo.getLength(); j++) { Node node = employeeInfo.item(j); NodeList employeeMeta = node.getChildNodes(); for (int k = 0; k < employeeMeta.getLength(); k++) { System.out.println(employeeMeta.item(k).getNodeName() + ":" + employeeMeta.item(k).getTextContent()); } } } System.out.println("解析完畢"); } catch (Exception e) { System.out.println(e.getMessage()); } }
2.SAX生成和解析XML文檔
為解決DOM的問題,出現了SAX。SAX ,事件驅動。當解析器發現元素開始、元素結束、文本、文檔的開始或結束等時,發送事件,程序員編寫響應這些事件的代碼,保存數據。優點:不用事先調入整個文檔,占用資源少;SAX解析器代碼比DOM解析器代碼小,適于Applet,下載。缺點:不是持久的;事件過后,若沒保存數據,那么數據就丟了;無狀態性;從事件中只能得到文本,但不知該文本屬于哪個元素;使用場合:Applet;只需XML文檔的少量內容,很少回頭訪問;機器內存少;
[java] view plaincopy
public void parserXml(String fileName) { SAXParserFactory saxfac = SAXParserFactory.newInstance(); try { SAXParser saxparser = saxfac.newSAXParser(); InputStream is = new FileInputStream(fileName); saxparser.parse(is, new MySAXHandler()); } catch (Exception e) { e.printStackTrace(); } }
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。