网络数据的XML解析
XML解析一般分兩種模式SAX和DOM,事件和文檔。具體解析google去吧,有詳細。不過看了下面的兩個例子,一般就了解了。
一:XML解析之SAX解析,以及對NSXMLParser的應用。
sax解析說白了,就是一個事物模型解析,從頭開始讀取文檔然后根據讀取到的頭標簽標簽時要怎么處理,讀完頭標簽后,理論上是讀取標簽值了,
然后讀取后遇到結束標簽等
SDK本身是提供了NSXMLParser解析器。
1 -(BOOL)parser:(NSString*)string 2 { 3 //系統自帶的 4 NSXMLParser *par = [[[NSXMLParser alloc] initWithData:[string dataUsingEncoding:NSUTF8StringEncoding]]autorelease]; 5 //設置NSXMLParser對象的解析方法代理 6 [par setDelegate:self]; 7 //調用代理解析NSXMLParser對象,看解析是否成功 8 return [par parse]; 9 } 10 11 #pragma mark xmlparser 12 //step 1 :準備解析 13 - (void)parserDidStartDocument:(NSXMLParser *)parser 14 { 15 // NSLog(@"%@",NSStringFromSelector(_cmd) ); 16 } 17 //step 2:準備解析節點 18 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 19 { 20 // NSLog(@"%@",NSStringFromSelector(_cmd) ); 21 } 22 //step 3:獲取首尾節點間內容 23 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 24 { 25 NSLog(@"%@",NSStringFromSelector(_cmd) ); 26 } 27 28 //step 4 :解析完當前節點 29 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 30 { 31 NSLog(@"%@",NSStringFromSelector(_cmd) ); 32 } 33 34 //step 5;解析結束 35 - (void)parserDidEndDocument:(NSXMLParser *)parser 36 { 37 // NSLog(@"%@",NSStringFromSelector(_cmd) ); 38 } 39 //獲取cdata塊數據 40 - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock 41 { 42 // NSLog(@"%@",NSStringFromSelector(_cmd) ); 43 }1.初始化解析器,傳入你要解析的數據。
2.parse,啟動解析,返回一個是否解析成功Bool值。
3.基本你要處理的就在下面實現的1-5個代理方法了。
其實代理方法和詳細,就是一個事物進行流程:
step1是準備解析,然后沒意外就是執行到了——>
step2讀取到第一個頭節點了,然后如果內部有屬性值,你可以獲取出來,讀完頭節點,我們會進去值域——>
step3對于簡單的節點,可能直接就是一個string值了,但是看例子我們會知道,很多情況下,該節點的值域包含的于是一個節點——>
這步其實分兩種,如果是值,那么就是執行step4,獲取值的字竄,如果是子節點呢,我們一看就知道,它又是進行了step2,
即讀取到頭標簽了,其實你是很人讀一片文章流程一樣,只不過我們腦中有個印象<xxx>是頭標簽了,我們要做什么,獨到 頭標簽的最后一個符號">"
下面進去值域,獨到了字竄的話就調用了foundCharacters:(NSString *)string,如果又讀到<xxx>這樣的,那就又是頭標簽了。——>
step5就是讀到開始尾標簽符號了。
最后一個方法
foundCDATA:(NSData *)CDATABlock,其實也是一個格式
<content:encoded> <![CDATA[ <img src="http://img1.douban.com/mpic/s10489201.jpg" style="float:right;margin-left:16px"/><a href="http://www.douban.com/people/maldini/">減卐肥?</a>評論: <a href="http://movie.douban.com/subject/6799191//">搜索</a><br/> <br/>評價: 力薦<br/><br/> ]]> </content:encoded>好了,方法和流程大致了解了,拿一個我最近遇到的例子,好多時候,我們會遇到這樣讀取一組類似于json中數組形式的數據
<channel> <title>我是標題</title> <link>http://write.blog.csdn.net/postedit</link> <description>...</description> <language>zh-cn</language> <pubDate>Fri, 03 Aug 2012 06:20:31 GMT</pubDate> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> </channel> 一般來說,我們要的數據其實都是這20個item,對吧,每個item下都是相同的3個標簽,title,author,time。形式上 其實一種數組形式 那么要怎么解析呢 1,首先我們可能先申明一個array數組容器用來存放這個20個對象,然后每個item對象中又有3個元素,那么我們可以 考慮用一個字典數據結構來表示每個item。 2.需要至少申請兩個空間來作為類似于“哨兵”存儲當前執行到的節點名,以及節點的值。 3.然后每次執行到讀取到item時,初始化我們上面說道的一個字典數據結構。 4.在foundCharacters:方法中一直保存當前最新的值(當然,這里面其實會有個小瑕疵,下面會說到)。 5.在標簽結束的方法,我們把標簽名和值已鍵值對存入上面初始化的字典容器中。 1 #pragma mark xmlparser 2 //step 1 :準備解析 3 - (void)parserDidStartDocument:(NSXMLParser *)parser 4 { 5 // NSLog(@"%@",NSStringFromSelector(_cmd) ); 6 7 parserObjects = [[NSMutableArray alloc]init]; 8 } 9 //step 2:準備解析節點 10 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 11 { 12 // NSLog(@"%@",NSStringFromSelector(_cmd) ); 13 14 self.currentText = [[NSMutableString alloc]init]; 15 [currentText release]; 16 if ([elementName isEqualToString:@"item"]) { 17 NSMutableDictionary *newNode = [[ NSMutableDictionary alloc ] initWithCapacity : 0 ]; 18 twitterDic = newNode; 19 [parserObjects addObject :newNode]; 20 [newNode release]; 21 } 22 else if(twitterDic) { 23 NSMutableString *string = [[ NSMutableString alloc ] initWithCapacity : 0 ]; 24 [twitterDic setObject :string forKey :elementName]; 25 [string release ]; 26 currentElementName = elementName; 27 } 28 29 30 } 31 //step 3:獲取首尾節點間內容 32 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 33 { 34 NSLog(@"%@",NSStringFromSelector(_cmd) ); 35 [currentText appendString:string]; 36 } 37 38 //step 4 :解析完當前節點 39 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 40 { 41 if ([elementName isEqualToString:@"item"]) { 42 twitterDic = nil; 43 }else 44 if ([elementName isEqualToString:currentElementName]) { 45 46 if ([elementName isEqualToString:@"description"] 47 ||[elementName isEqualToString:@"content:encoded"]) { 48 [twitterDic setObject:Cdata forKey:currentElementName]; 49 }else { 50 [twitterDic setObject:currentText forKey:currentElementName]; 51 } 52 } 53 54 } 55 56 //step 5;解析結束 57 - (void)parserDidEndDocument:(NSXMLParser *)parser 58 { 59 } 60 //獲取cdata塊數據 61 - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock 62 { 63 Cdata =[[NSString alloc] initWithData:CDATABlock encoding:NSUTF8StringEncoding]; 64 } 二:Dom文檔解析模型,TBXML第三方包應用。 dom解析模型就像一個樹結構,節點,子節點,兄弟節點等等。 這個其實最后被我拋棄了,這個解析器太簡化了,太簡潔的東西導致控制的入口點太少,就比如一個一鍵優化的軟件的概念是一樣的,一鍵清楚緩存,優化配置,文件歸類等等。人為控制就少了,導致我解析上面那個模型時,只知道遍歷存儲~。但是這個解析期對部分要求不高的xml解析其實挺好分,真的很簡潔。 1 - (void)recurrence:(TBXMLElement *)element { 2 3 NSString *eleName = [TBXML elementName:element]; 4 NSString *eleText = [TBXML textForElement:element]; 5 if ([eleName isEqualToString:@"item"]) { 6 self recurrence:element 7 } 8 do { 9 10 NSString *eleName = [TBXML elementName:element]; 11 NSString *eleText = [TBXML textForElement:element]; 12 13 //遞歸處理子樹 14 if (element->firstChild) { 15 NSLog(@"<%@>:",eleName);// Display the name of the element 16 17 [self recurrence:element->firstChild]; 18 }else { 19 NSLog(@"<%@>:%@",eleName,eleText);// Display the name of the element 20 21 TBXMLElement *parent = element->parentElement; 22 if ([[TBXML elementName:parent] isEqualToString:@"item"]) { 23 NLRssInfo *info = [[[NLRssInfo alloc]init] autorelease]; 24 25 if ([eleName isEqualToString:@"title"]) { 26 info.title = eleText; 27 } 28 29 [dataArr addObject:info]; 30 } 31 32 } 33 34 //迭代處理兄弟樹 35 } while ((element = element->nextSibling)); 36 } 37 38 - (void) dealloc 39 { 40 [title release]; 41 [subtitle release]; 42 [super dealloc]; 43 } 遞歸遍歷,常規的樹操作,具體內容可以網上搜搜,很多。 并且開源庫的好處就是有源代碼,也就3個類,6個文件,有興趣可以研究研究,貌似大部分代碼是用C寫的。?
轉載于:https://www.cnblogs.com/tryingx/articles/3715243.html
總結
以上是生活随笔為你收集整理的网络数据的XML解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring MVC 中的 forwar
- 下一篇: 写个随笔