─━ IT ━─

Swift의 XML 구문 분석 초급 가이드

DKel 2020. 12. 27. 01:23
반응형

XML 구문을 사용하는 수많은 문서 형식(예: RSS, Atom, SOAP 및 XHTML)이 개발되었으므로 문서 작업 방법을 알고 있으면 좋습니다. XML에 익숙하지 않은 경우 기본적으로 정확하게 포맷된 텍스트 또는 문자열로, 이 텍스트는 중요한 정보를 포함하는 개체 배열로 구문 분석할 수 있습니다.

XML에 대한 좋은 자습서는 여기에서 찾을 수 있습니다.

=> www.w3schools.com/xml/

 

XML Tutorial

XML Tutorial XML stands for eXtensible Markup Language. XML was designed to store and transport data. XML was designed to be both human- and machine-readable. XML Example 2     Belgian

www.w3schools.com

 

 

GitHub의 NSXMLParser(iOS SDK의 일부) 및 SWXMLHash의 사용법을 보여드리겠습니다. 

=> github.com/drmohundro/SWXMLHash

 

drmohundro/SWXMLHash

Simple XML parsing in Swift. Contribute to drmohundro/SWXMLHash development by creating an account on GitHub.

github.com


도움이 될 XML 샘플은 다음과 같습니다.

<items>
	<item>
		<author>Robi</author>
		<description>My article about Olympics</description>
		<tag name = "Olympics" count = "3"/>
		<tag name = "Rio"/>
	</item>
	<item>
		<author>Robi</author>
		<description>I can't wait Spa-Francorchamps!!</description>
		<tag name = "Formula One"/>
		<tag name = "Eau Rouge" count = "5"/>
	</item>
</items>


NSXML 파서부터 살펴보겠습니다.
먼저 맞춤형 개체를 생성해야 합니다.

class Item { 
    var author = "";
    var desc = "";
    var tag = [Tag]();
}

class Tag {
    var name = "";
    var count: Int?;
}


보시다시피 각 멤버에 대해 별도의 클래스를 만들었는데, 이 클래스는 상위 멤버 내에서 여러 값을 가져올 수 있습니다(그래서 배열을 만들수도 있습니다).

NSXMLParser를 사용하려면 NSXMLParserDelegate 클래스를 사용해야 합니다.

XML 파일을 Xcode에 맞게 다이제스트할 수 있도록 하고, 파서를 생성하고, 위임자를 설정해야 합니다

(샘플 데이터의 이름이 xmlString이 될 수 있음).

let xmlData = xmlString.dataUsingEncoding(NSUTF8StringEncoding)!
let parser = NSXMLParser(data: xmlData)
        
parser.delegate = self;
        
parser.parse()


NSXMLParserDelegate에게 다양한 기능이 제공되지만, 이 중 4개 기능만 흥미롭게 느껴집니다.

1. funcparser(didStartElement): 파서가 a를 찾을 때마다 호출됩니다. 예에서 파서가, , …에 도달하면 호출됩니다.
2. funcparser(didEndElement): 파서가 a를 찾을 때마다 호출됩니다. 우리의 예에서는 파서가, , …에 도달하면 호출됩니다.
3. funcparser(찾은 문자): 파서가 a에 들어갈 때마다 호출되며, 이는 온라인 중단과 "특수 문자"(예: i, ö)에서 중지됩니다. 두 번째 부분은 문제처럼 보이지만, 파서의 가장 일반적인 사용으로 이 문제는 완전히 해결되었습니다(나중에 더 많이 사용).
4. funcparserDidEndDocument: 파서가 문서를 마쳤을 때 호출됩니다. 파서는 전체 문서를 한 번 실행합니다. 즉, 파서가 키, 다음 문자로 시작하고("Robi", "DidEndElement"에서 "didEndElement"에서 "doEndElement on"에서 발견된 문자 다음에 이어 다음 문자로 시작합니다.
이제 파서가 어떻게 작동하는지 알았으니 원소들을 분석해야 합니다. 이를 위해서는 새 항목 배열, 발견된 문자에 대한 빈 문자열 및 글로벌 항목 변수가 필요합니다(위임자의 메서드를 여러 번 호출하고 완료할 때까지 구문 분석된 값을 저장해야 하기 때문에 필요함).

var items = [Item]();
var item = Item();
var foundCharacters = "";


NSXMLParserDelegate 의 함수는 다음과 같이 작성합니다.

func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
	if elementName == "tag" {
		let tempTag = Tag();
		if let name = attributeDict["name"] {
			tempTag.name = name;
		}
		if let c = attributeDict["count"] {
			if let count = Int(c) {
				tempTag.count = count;
			}
		}
		self.item.tag.append(tempTag);
	}
}


보시다시피 인라인 값()이 있으면 didEndElement를 사용할 수 없습니다. 값이 없기 때문입니다.

다행히도 Dict [String: String] 딕셔너리가 있습니다. 어떤 가치를 얻고자 하는지 보기만 하면 됩니다.

func parser(parser: NSXMLParser, foundCharacters string: String) {
	self.foundCharacters += string;
}


또 다른 것은 문자 변수입니다.

위에서 언급했듯이, 파서(발견된 문자) 기능은 중단될 수 있지만..

NSXMLParser는 전체 문서를 동시에 구문 분석하므로 파서가 중지된 위치에서 계속됩니다.

func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
	if elementName == "author" {
		self.item.author = self.foundCharacters;
	}
        
	if elementName == "description" {
		self.item.desc = self.foundCharacters;
 	}
        
	if elementName == "item" {
		let tempItem = Item();
		tempItem.author = self.item.author;
		tempItem.desc = self.item.desc;
		tempItem.tag = self.item.tag;
		self.items.append(tempItem);
		self.item.tag.removeAll();
	}
	self.foundCharacters = ""
}


파서가 요소의 끝에 도달하면 발견된 문자 값을 비웁니다.

따라서, 이 item 들은 우리가 원하는 문자열을 제공합니다.

 

반응형