XML 구문을 사용하는 수많은 문서 형식(예: RSS, Atom, SOAP 및 XHTML)이 개발되었으므로 문서 작업 방법을 알고 있으면 좋습니다. XML에 익숙하지 않은 경우 기본적으로 정확하게 포맷된 텍스트 또는 문자열로, 이 텍스트는 중요한 정보를 포함하는 개체 배열로 구문 분석할 수 있습니다.
XML에 대한 좋은 자습서는 여기에서 찾을 수 있습니다.
GitHub의 NSXMLParser(iOS SDK의 일부) 및 SWXMLHash의 사용법을 보여드리겠습니다.
=> github.com/drmohundro/SWXMLHash
도움이 될 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 들은 우리가 원하는 문자열을 제공합니다.