こんばんは。寒くなりましたね〜
最近、以前(iOS5頃)に開発したアプリのiOS8対応をチョコチョコと進めています。
そこでXMLのパース処理もSwiftで書き直してみたのでメモ。。
読み込むXMLのサンプル
<?xml version="1.0" encoding="UTF-8"?>
<Items>
<Item>
<ItemName>AAA</ItemName>
<Price>100</Price>
</Item>
<Item>
<ItemName>BBB</ItemName>
<Price>200</Price>
</Item>
</Items>
XMLのパースにはNSXMLParserを使いました
var parser : NSXMLParser? = NSXMLParser(data: data)
if parser != nil {
// NSXMLParserDelegateをセット
parser!.delegate = self;
parser!.parse()
} else {
// パースに失敗した時
println("failed to parse XML")
}
NSXMLParserDelegateを設定したクラスのプロパティ
var _ParceKey: String! = ""
var _Items: [Item]? = nil
var _Item: Item? = nil
XML読み込み開始時に呼ばれます
func parserDidStartDocument(parser: NSXMLParser!)
{
// Itemオブジェクトを格納するItems配列の初期化など
}
XML読み込み完了時に呼ばれます
func parserDidEndDocument(parser: NSXMLParser!)
{
// XMLから読み込んだ情報より画面を更新する処理など
}
タグの最初で呼ばれます
例えばItemsタグやItemタグ、ItemNameタグの読み込み開始時に呼ばれる
func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: NSDictionary!)
{
_ParseKey = elementName
if elementName == "Items" {
// Itemオブジェクトを保存するItems配列を初期化
_Items = []
} else if elementName == "Item" {
// Itemオブジェクトの初期化
_Item = Item()
}
}
タグの最後で呼ばれます
例えばItemsタグやItemタグ、ItemNameタグの読み込み完了時に呼ばれる
func parser(parser: NSXMLParser!, didEndElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!)
{
if elementName == "Item" {
_Items!.append(_Item!)
}
_ParseKey = ""
}
各項目を読み込み
func parser(parser: NSXMLParser!, foundCharacters string: String!)
{
if _ParseKey == "ItemName" {
_Item!.itemName = string
} else if _ParseKey == "ItemPrice" {
_Item!.itemPrice = string.toInt()
} else {
// nop
}
}
最後に・・
ざっとこんな感じでXMLが読み込めますが、ちょっと面倒クサイ感がありますね。。
XMLのAttributeを特に使わない場合は、Jsonを使った方が簡単にDictionaryに格納できて便利そうです。
_ParseKeyや_Items, _Itemの使い方もこんな感じでよいのかちょっと気になりますが、一旦これで。。
Optional変数の"?"や"!"の使い方が怪しいところがありますがご容赦ください。。勉強します!