LoginSignup
3
2

More than 5 years have passed since last update.

Swift でXMLパースしてみました。

Last updated at Posted at 2018-05-06

Swift でXMLパース

Overview

swiftでXMLパースをしてみました。

OSSでは下記を見つけました

上記2点以外にもXMLパーサーは存在しているかもしれませんが、

今回はこの2点を列挙させていただきました。

実際にパースしてみたのは drmohundro/SWXMLHash になります。
yahoojapanのXMLパーサーも影響を受けたそうですので、こちらにしてみました。

Use it

Cocoapods

To install CocoaPods, run:

$ gem install cocoapods
Podfile
platform :ios, '10.0'
use_frameworks!

target 'YOUR_TARGET_NAME' do
  pod 'SWXMLHash', '~> 4.0.0'
end

Podfileに上記を記述し、下記を実行します。


$ pod install

通信クラスには下記を使います

keisukeYamagishi/HttpSession

TCP / IP based HTTP communication can be simplified

なのでPodfileは下記のようにします。

Podfile
platform :ios, '10.0'
use_frameworks!

target 'YOUR_TARGET_NAME' do
  pod 'SWXMLHash', '~> 4.0.0'
  pod 'HttpSession'
end

$ pod install

下記のようなXMLをパースする場合の使い方になります。


<rest order="0">
<id>6363054</id>
<update_date>2017-12-10 05:04:30</update_date>
<name>餃子の安亭 新宿店</name>
<name_kana>ギョウザノアンテイシンジュクテン</name_kana>
<latitude>35.690078</latitude>
<longitude>139.702786</longitude>
<category>餃子</category>
<url>
https://r.gnavi.co.jp/efk1099b0000/?ak=Dil4xinerVDUdo2%2BMpaU4uwlSorYa1jve%2BRSBbdUIAQ%3D
</url>
<url_mobile>
http://mobile.gnavi.co.jp/shop/6363054/?ak=Dil4xinerVDUdo2%2BMpaU4uwlSorYa1jve%2BRSBbdUIAQ%3D
</url_mobile>
<coupon_url>
<pc/>
<mobile/>
</coupon_url>
<image_url>
<shop_image1/>
<shop_image2/>
<qrcode>https://c-r.gnst.jp/tool/qr/?id=6363054&q=6</qrcode>
</image_url>
<address>〒160-0023 東京都新宿区西新宿1-2-1 ファイブKビル2F</address>
<tel>03-5323-8228</tel>
<tel_sub/>
<fax/>
<opentime>
11:30~15:00(L.O.14:45)(平日)、17:00~23:30(L.O.23:00)(平日)<BR>土・日・祝日 11:30~23:30(L.O.23:30)(ランチ~14:30)
</opentime>
<holiday/>
<access>
<line>都営大江戸線(環状部)</line>
<station>新宿西口駅</station>
<station_exit>D3口</station_exit>
<walk>徒歩1</walk>
<note/>
</access>
<parking_lots/>
<pr>
<pr_short/>
<pr_long/>
</pr>
<code>
<areacode>AREA110</areacode>
<areaname>関東</areaname>
<prefcode>PREF13</prefcode>
<prefname>東京都</prefname>
<areacode_s>AREAS2120</areacode_s>
<areaname_s>新宿西口・都庁前</areaname_s>
<category_code_l order="0">RSFST14000</category_code_l>
<category_name_l order="0">中華</category_name_l>
<category_code_s order="0">RSFST14008</category_code_s>
<category_name_s order="0">餃子</category_name_s>
<category_code_l order="1"/>
<category_name_l order="1"/>
<category_code_s order="1"/>
<category_name_s order="1"/>
</code>
<budget/>
<party/>
<lunch/>
<credit_card/>
<e_money/>
<flags>
<mobile_site>1</mobile_site>
<mobile_coupon>0</mobile_coupon>
<pc_coupon>0</pc_coupon>
</flags>
</rest>

パースしたいxmlの構造を下記のようにコーディングします。

これを配列として扱ってやるとやってくれます。


public struct Rest: XMLIndexerDeserializable {
    var name: String = ""
    var latitude: String = ""
    var longitude: String = ""
    var address: String = ""
    var url: String = ""
    init(name: String, latitude:String, longitude: String, address:String, url:String){
        self.name = name
        self.latitude = latitude
        self.longitude = longitude
        self.address = address
        self.url = url
    }
    public static func deserialize(_ node: XMLIndexer) throws -> Rest {
        return try Rest (
            name: node["name"].value(),
            latitude: node["latitude"].value(),
            longitude: node["longitude"].value(),
            address: node["address"].value(),
            url: node["url"].value()
        )
    }
}

let r: [Rest] = try xml["response"]["rest"].value()

全体像はこんな感じです。


//
//  ViewController.swift
//  DEMO
//
//  Created by Shichimitoucarashi on 2018/05/06.
//  Copyright © 2018年 keisuke yamagishi. All rights reserved.
///Users/keisukeyamagishi/Code/GAME/DEMO/DEMO/ViewController.swift:42:32: Argument passed to call that takes no arguments

import UIKit
import HttpSession
import SWXMLHash

public struct Rest: XMLIndexerDeserializable {
    var name: String = ""
    var latitude: String = ""
    var longitude: String = ""
    var address: String = ""
    var url: String = ""
    init(name: String, latitude:String, longitude: String, address:String, url:String){
        self.name = name
        self.latitude = latitude
        self.longitude = longitude
        self.address = address
        self.url = url
    }
    public static func deserialize(_ node: XMLIndexer) throws -> Rest {
        return try Rest (
            name: node["name"].value(),
            latitude: node["latitude"].value(),
            longitude: node["longitude"].value(),
            address: node["address"].value(),
            url: node["url"].value()
        )
    }
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

      Http(url:"https://api.gnavi.co.jp/RestSearchAPI/20150630/?keyid=ed0508a689013e2c064187189fc3c568&latitude=35.6900488&longitude=139.7028957&", method: .get)
            .session { (data, responce, error) in

                do{
                    let xml = SWXMLHash.parse(data!)

                    let r: [Rest] = try xml["response"]["rest"].value()
                    print (r)
                }catch{

                }

        }
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2