2011年8月29日

XML Parser心得分享(1)-NSXML

有網友留言問到XML處理,就把之前的草稿完成一下
怕文章太長不好讀,拆成兩篇寫
寫到現在遇過挺多處理case要xml資料
目前用過的XML parser有內建的NSXML和TBXML


這篇先簡單說明一下NSXMLParserDelegate三個重要的函式:




以下是一個XML 範例:來自W3C school.com
<note>
<to>Tove</to>
 <from>Jani</from>
 <heading>Reminder</heading>
 Don't forget me this weekend!
</note>


當讀到start tag的時候觸發這個delegate:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName   namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qualifiedName
    attributes:(NSDictionary *)attributeDict
也就是這些地方:
<note>
<to>Tove</to>
 <from>Jani</from>
 <heading>Reminder</heading>
 Don't forget me this weekend!
</note>


當讀到end tag的時候觸發這個delegate:
- (void)parser:(NSXMLParser *)parser
 didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qName
也就是這些地方:
<note>
<to>Tove</to>
 <from>Jani</from>
 <heading>Reminder</heading>
 Don't forget me this weekend!
</note>


當讀到xml內容的時候觸發這個delegate:
 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string

也就是這些地方:
<note>
<to>Tove</to>
 <from>Jani</from>
 <heading>Reminder</heading>
 Don't forget me this weekend!
</note>


另外描述一下各個參數:
parser:從哪個parser delegate過來
elementName:tag叫什麼名字,例如note
namespaceURI:有些xml會有name space,如<book:name> 的book
qName:namespaceURI:elementName
attributeDict:如果tag有attribute,會存成NSDictionary

所以流程大概是:
1.didStartElement的時候紀錄一些需要的資訊,如elementName
2.foundCharacters的時候把內容暫存起來
3.didEndElement的時候存到目標物件(比如說自定一個物件來存heading)

有幾個要點:
1.只有標籤夾字的其實在endElement處理就可以了(如上面例子的所有標籤)
2.foundCharacters的時候因為是一個一個字元讀到,可用[bufString appendString:string]存
3.然後記得每次找到字後要清空buffer
4.簡單的xml可以善用elementName當key,內容當值,存成NSDictionary的格式,來減少每次都要重建新物件的麻煩

但xml格式太多種(可能是巢狀、有name space),每次遇到新內容多少還是得重新想一次delegate怎麼寫,實在有點麻煩
 如果有路過的高手看到,覺得有好寫法的,還請指教了


其他相關的XML parser library以及效能比較可參考這篇文章:
How To Choose The Best XML Parser for Your iPhone Project 

3 則留言:

伍林森 提到...

非常感谢你 不知道你在图文混排方面有没有什么经验可以分享~

kenobiluh 提到...

這件事就比較複雜了,不太知道您打算達成什麼功能?

Unknown 提到...

謝謝分享