此份文件為個人學習事件驅動XML程式的翻譯,內文請參考蘋果官方文件,若有翻譯錯誤請見諒,請勿挪作商業用途,並著明出處。
使用NSXMLParser來解析一份XML文件的必要步驟是很 直觀的。它需要完成下列步驟:
使用NSXMLParser來解析一份XML文件的必要步驟是很
- Locate the XML.
- 創建並初始化NSXMLParser的實例,
並確認你設定好了委任。 - 實作你有興趣的委任方法。
- 處理任何解析錯誤。
- Locate
the XML.
表一展示了讓使用者從檔案系統瀏覽(file-system browser(NSOpenPanel))中選取一個XML檔案的程式碼。 - (void)openXMLFile {
NSArray *fileTypes = [NSArray arrayWithObject:@"xml"];
NSOpenPanel *oPanel = [NSOpenPanel openPanel];
NSString *startingDir = [[NSUserDefaults standardUserDefaults] objectForKey:@"StartingDirectory"];
if (!startingDir)
startingDir = NSHomeDirectory();
[oPanel setAllowsMultipleSelection:NO];
[oPanel beginSheetForDirectory:startingDir file:nil types:fileTypes
modalForWindow:[self window] modalDelegate:self
didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
contextInfo:nil];
}
- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo {
NSString *pathToFile = nil;
if (returnCode == NSOKButton) {
pathToFile = [[[sheet filenames] objectAtIndex:0] copy];
}
if (pathToFile) {
NSString *startingDir = [pathToFile stringByDeletingLastPathComponent];
[[NSUserDefaults standardUserDefaults] setObject:startingDir forKey:@"StartingDirectory"];
[self parseXMLFile:pathToFile];
}
}
雖然一份XML檔案是一般的情況,XML的資源(resource)也許不是一份檔案。 你可以從像是屬性列表物件(property-list object,像NSDictionary)或是透過網路( network)的位元串流(stream of bytes)接收到XML。像這樣的情況, 你必須在初始化NSXMLParser實例前(參考下列步驟) 先轉換XML的形式成NSData物件。 - 創建並初始化NSXMLParser的實例,
並確認你設定好了委任。
表二:創建和初始化NSXMLParser實例- (void)parseXMLFile:(NSString *)pathToFile {
BOOL success;
NSURL *xmlURL = [NSURL fileURLWithPath:pathToFile];
if (addressParser) // addressParser is an NSXMLParser instance variable
[addressParser release];
addressParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
[addressParser setDelegate:self];
[addressParser setShouldResolveExternalEntities:YES];
success = [addressParser parse]; // return value not used
// if not successful, delegate is informed of error
}
在這個方法,客制物件(client object)轉換XML檔案路徑成一個NSURL物件,然後使用那個物件去以initWithContentsOfUR L:方法初始化NSXMLParser的實例。 它也將它自己設定成委任, 並讓parser知道他要去解決外部實體(resolve external entity)(像是外部DTD宣告)。 其他的NSXMLParser方法讓你設定多個命名空間相關選擇 。最後, 客制物件將parse送到NSXMLParser實例來開始解析 XML。
若XML不是檔案的形式,你要把它轉換成一個NSData物件,然後使用initWithData:初始子來出初始化它: addressParser = [[NSXMLParser alloc] initWithData:xmlData];
- 實作你有興趣的委任方法。
當NSXMLParser物件解析XML時,它為它所遇到的每一個XML建構送訊息到它的委任( 但只有委任實作了相關方法時才會如此)。 這些方法的實作隨著建構的不同而改變:DTD宣告、 命名空間首字母(namespace prefix)、元素等等。 元素是最XML建構裡面最普遍的種類,參考Handling XML Elements and Attributes。
所有的解析操作開始於委任接收到parserDidStartDocument:方法, 並結束於委任接收到parserDidEndDocument: 方法(當然,這也要委任有實作這些方法)。 前一個方法提供分配空間(allocating) 和設定解析操作所需要的資源(resource), 後一個方法是適合去釋放那些資源和適當的處理任何結果的地方。
- 處理任何解析錯誤。
若parser遇到錯誤,它會停止解析並且喚起委任方法parser:parseErrorOccurred:。 實作這個方法去說明錯誤和通知使用者。( 所有的parser錯誤都不能回復),參考“Handling Parsing Errors。
當你解析XML時,記憶體管理變的很重要。處理XML常常要你去創建很多物件, 你不應讓這些物件在用完後仍佔據記憶體(accumulate in memory past their span of usefulness)。一個處理這些產生的物件的技巧是, 讓委任再每個委任方法十作開始時去創建局部自動釋放池, 並在回傳前釋放自動釋放池。 NSXMLParser為它所創建的每個物件管理記憶體, 並傳送到委任。
留言
張貼留言