iOS / SwiftでXMLをパース

  • 45
    いいね
  • 1
    コメント
この記事は最終更新日から1年以上が経過しています。

こんばんは。寒くなりましたね〜

最近、以前(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変数の"?"や"!"の使い方が怪しいところがありますがご容赦ください。。勉強します!