解放区在住氷翠 緑の閃光
【解放区在住氷翠】デスクトップアプリケーション

【Swift】XMLデータを書き込みたい

2023-05-11

氷翠です。

前回、XMLファイルの読み込みに挑戦していました。そして、今回は書き込み…つまりは保存に挑戦してみました。

今回は単純にデータを保存するだけなので、Viewに関してはボタンを配置するだけ。

こんな感じ。

また、最終的にXMLデータはこんな感じで。

こんな感じのデータ構造を目的とする。

あとはボタンのアクションに対して、データを保存する処理を行っていく。ここまでは通常通り。そして書き込み用のクラスを別ファイルにして作成することにする。

import Foundation

/*
 structを利用してデータの形を作り出す。
 */
struct item {
    var itemNo   : String
    var itemName : String
    var value    : String
}

class xmlWrite {
    // XML全体の文字列
    var contents : String = ""
    // 保存するデータ
    // 先にここで書き込むデータを用意しておく
    let data : [item] = [
        item(itemNo: "1", itemName: "Item Name C", value: "value C"),
        item(itemNo: "2", itemName: "Item Name D", value: "value D")
    ]
    
    // version等
    let doc = XMLDocument()
    
    // FileManager.defaultを利用するため、そのメソッドまでを短縮します
    let fm = FileManager.default
    
    // root
    var root : XMLElement = XMLElement(name: "root")
    
    /*
     クラスが呼び出された時点で、最初の1行目を作成しておく
     */
    init() {
        self.doc.version = "1.0"
        self.doc.characterEncoding = "UTF-8"
        self.contents = self.doc.xmlString + "\n"
    }
    
    func write() -> String {
        var output = ""
        // XMLデータの作成
        self.data.forEach { d in
            // <items itemNo="1">
            let items = XMLElement(name: "items")
            // この部分では属性もついている。
            let itemNo = XMLNode(kind: .attribute)
            itemNo.name = "itemNo"
            itemNo.stringValue = d.itemNo
            items.addAttribute(itemNo) // ここで属性を付与する
            // itemsの中身を作成
            // タグを作成
            let itemName = XMLElement(name: "itemName")
            // データを準備
            itemName.stringValue = d.itemName
            // 1行分を親要素に追加する
            items.addChild(itemName)
            // 以下は上記を1行にまとめた感じになる
            let value = XMLElement(name: "value", stringValue: d.value)
            // これも親要素に追加
            items.addChild(value)
            // itemsをrootに追加
            self.root.addChild(items)
        } // end forreach
        // 作成したデータを文字列に変換
        let cont = self.root.xmlString
        // 大元の文字列に追加
        self.contents += cont
        // self.contentsすべての文字列の中はほぼ1行になっているので、
        // せめて各タグごとに改行を入れておこうかと思います。
        self.contents = self.contents.replacingOccurrences(of: "><", with: ">\n<")
        // データの保存
        // 以下のプログラムは普通にテキストファイルに保存する
        guard let path = fm.urls(for: .desktopDirectory, in: .userDomainMask).first else {
            fatalError("URL取得失敗")
        }
        let fullURL = path.appendingPathComponent("text_write.xml")
        do {
            try self.contents.write(to: fullURL, atomically: true, encoding: .utf8)
            output = "保存完了"
        } // end do
        catch {
            output = "保存失敗"
        } // end catch
        return output
    }
}

説明も上のコードの中にあるので、説明は不要かもしれないが、「XMLDocument()」とか「XMLElement」とかでタグを生成したりしていく。

でその形は意外と簡単にできるので、XML形式でデータを保管するのは楽でいいかも。と考えます。

最終的にはテキストファイルになるわけだから、そのデータを文字列に変換する。すると、1行になっている。改行が一切ないので、さすがに直接ファイルを開いくと1行になっているのは見づらいw

そこで「><」ってなっている部分に改行を挟めて、開始タグの部分にスペースをいれて見やすくする。その状態で通常通りの方法でファイルに保存しておく。

コメントを残す

メールアドレスが公開されることはありません。