iOS XML parser NSXMLParser[1]

Programming/Objective-C 2012. 4. 20. 00:43

iOS에서 사용할 수 있는 XML 파서가 꽤 많다. 대체적으로 메모리 사용량이나 속도면에서 TBXML을 많이 사용하는 듯 하다. 무료도 제공되는 라이브러리가 성능면에서는 좋은 것 같은데... 문제는 iOS의 빠른 업데이트를 따라가려면 좀 시간이 걸린다는 것... TBXML에서는 아직 xCode에서 업데이트 된 ARC(Automatic Reference Counting)를 지원하지 않는 것 같아서 일단 기본 제공되는 NSXMLParser 사용법 부터 정리해 보기로 한다.


NSXMLParser도 delegate 메소드를 통해서 element의 값들에 접근할 수 있다. iOS를 공부하면서 가장 이해하기 어려웠던 부분이 바로 delegate 메소드 호출방식이었다. 전혀 속도면에서 도움이 될 것 같지 않은 방법을 채택하고 있는지라 초기에는 왜 이렇게 해야만하는지에 대한 의문에 사로잡혀 있다보니 한 없이 복잡하고 어려웠다. 아무튼 공부는 이해가 안되면 그냥 정신줄을 놓고 외워서 받아들이는 편이 정신 건강에 좋다.


본론으로 들어가서... 본인도 틈틈히 개인적으로 공부하는 차원에서 정리하고 있기 때문에 내용에서 오류가 발견될 수도 있다. 오류가 있으면 알려주시면 좋겠다. 


NSXMLParser는 parse 메소드에 메시지를 전달하면 delegate로 연결된 객체에서 처리해 놓은 일련의 메소드들을 호출하면서 파싱을 진행한다. 아래는 NSXMLParser가 파싱을 하면서 실행되는 메소드들의 순서다.


NSXMLParser 객체 parse 메소드 호출 후,

1. parserDidStartDocument

2. didStartElement

3. foundCharacters

4. didEndElement

5. parserDidEndDocument


이 과정에서 오류가 발견되면 parseErrorOccurred 메소드가 호출된다.


아래는 샘플로 활용할 xml 내용이다.


<?xml version="1.0" encoding="UTF-8"?> <catalog> <book id="bk101"> <author>Gambardella, Matthew</author> <title>XML Developer's Guide</title> <genre>Computer</genre> <price>44.95</price> <publish_date>2000-10-01</publish_date> <description>An in-depth look at creating applications with XML.</description> </book> </catalog>


일단 번들에 있는 xml 데이터를 불러와서 파싱을 시작한다.

NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"sample.xml"];
    NSData *data = [NSData dataWithContentsOfFile:path];
    
    self.xmlParser = [[NSXMLParser alloc] initWithData:data];
    self.xmlParser.delegate = self;
    if([self.xmlParser parse]){
        NSLog(@"The XML is Parsed.");
        
    }else {
        NSLog(@"Failed to parse the XML");
    }

[self.xmlParser parse] 메소드를 호출하여 파싱을 시작하면 처음으로 호출되는 메소드는 parserDidStartDocument 

-(void) parserDidStartDocument:(NSXMLParser *)parser{
      NSLog(@"parserDidStartDocument");
      // tab 처리를 위한 전역 변수
      tabString = [NSMutableString new];
}

그리고 순차적으로 element들을 탐색하기 시작한다. 각 element에 접근할 때마다 아래 메소드가 실행된다.


-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
                                          namespaceURI:(NSString *)namespaceURI 
                                          qualifiedName:(NSString *)qName 
                                          attributes:(NSDictionary *)attributeDict{
      tabString = [[tabString stringByAppendingString:@"\t"] mutableCopy];
      NSLog(@"%@", [tabString stringByAppendingString:elementName]);
      
}

elementName가 각 element명이다. 여기서는 NSLog 쓸 때 tab을 하나씩 추가하여 들여쓰기를 한다.  해당 노드의 attribute들은 NSDictionary형으로 attributeDict을 참조해서 사용하면 된다.


그 다음으로 실행되는 것이 아래 메소드다.


-(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
      NSLog(@"%@", [tabString stringByAppendingString:string]);
}

didStartElement 메소드에서 접근한 element의 value 값을 확인할 수 있다. 그 다음으로는 element의 값까지 접근했으니 element가 닫히는 부분이다. 여기서는 일단 elementName을 출력하고 tabString의 끝에 있는 '\t'을 하나씩 제거하여 들여쓰기를 전 단계로 되돌린다.


-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
                                          namespaceURI:(NSString *)namespaceURI 
                                          qualifiedName:(NSString *)qName{
      NSLog(@"%@", [tabString stringByAppendingString:elementName]);
      tabString = [[tabString substringToIndex:[tabString length]-1] mutableCopy];
}

 

이렇게 뎁스 안쪽으로 탐색을 하여 값을 참조하고 밖으로 나오면서 최종 root element를 닫으면 아래 메소드가 실행되고 parsing을 종료하게 된다. 


-(void) parserDidEndDocument:(NSXMLParser *)parser{
      NSLog(@"parserDidEndDocument");
      tabString = nil;
}


output 결과 >

parserDidStartDocument
	catalog
	
   
		book
		
      
			author
			Gambardella, Matthew
			author
		
      
			title
			XML Developer's Guide
			title
		
      
			genre
			Computer
			genre
		
      
			price
			44.95
			price
		
      
			publish_date
			2000-10-01
			publish_date
		
      
			description
			An in-depth look at creating applications 
      with XML.
			description
		
   
		book
	

	catalog
parserDidEndDocument
The XML is Parsed.


element value가 없는 것들도 메소드는 실행되기 때문에 줄 내림이 생기는 것을 알 수 있다. 

이제 해야할 일은 각 element와 attribute에 접근하여 값을 확인할 수 있으니 이것을 나름의 데이터에 저장해서 활용하면 된다. 다음 포스트에서는 참조된 데이터를 저장하여 사용하는 부분을 추가하도록 하겠다.



    

설정

트랙백

댓글