LoginSignup
2
4

More than 5 years have passed since last update.

【Swift】NSXMLParserで文字列にアルファベットや数字、マルチバイト文字が含まれる場合、複数に分かれてパースされる件

Posted at

SwiftでXMLをパースする際に、
NSXMLParserを使用するのですが、以下のような要素をパースする際に


<ele>aaa あいうえお abcd 春夏秋冬 123</ele>

マルチバイト+アルファベット文字列が要素内であったとすると、
それぞれ分かれて、一回目aaaで二回目あいうえお、三回目abcdの形で取得できてしまって、
一気に取れないのが不便。

フラグとかはないので手動で配列に貯めてから、閉じタグを読み込んだ時にreduceで再帰的に足して取得する

実装

NSXMLParserDelegateを指定

    var isTitle:Bool=false
    var parsedStrArr:Array<String>!
    var entries : NSMutableArray!
    var tmpEntry : NSMutableArray!

    override func viewDidLoad() {
        super.viewDidLoad()
        loadRss()
    }

    func loadRss() {

        // Sample feed url
        let rUrl: NSURL = NSURL(string: "https://hoge.co.jp/feed/?cat=5")!
        let rssUrl = rUrl

        parser = NSXMLParser(contentsOfURL: rssUrl)!
        parser.delegate = self

        //以下の1行の処理でparse関連の処理が行われる。
        let success:Bool = parser.parse()
        if success {
            print("パース成功")
        } else {
            print("パース失敗")
        }
    }

    // NSXMLParserDelegate
    // ここから下はParse関連処理

    func parserDidStartDocument(parser: NSXMLParser){
        entries = NSMutableArray()
    }

    // 開始タグを読み込んだ時よばれる - Start
    func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [NSObject : AnyObject]) {

        parsedStrArr = []

        if (elementName == "title"){
          // 配列初期化
            tmpEntry = NSMutableArray()
            entries.addObject(tmpEntry)
            isTitle = true;
        }
    }

    //閉じタグを読み込んだ時よばれる - End
    func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {

        if (elementName == "title"){
            // reduceによる再帰処理で文字列を足す
            tmpEntry.addObject(parsedStrArr.reduce(String()) { $0 + $1 })
            isTitle = false
        }
    }

    //タグ以外のテキストを読み込んだ時(タグとタグ間の文字列)
    func parser(parser: NSXMLParser, foundCharacters string: String?) {

        if(isTitle && tmpEntry != nil){
            // タイトル内文字列を追加していく
            parsedStrArr.append(string!)
        }
    }

    func parserDidEndDocument(parser: NSXMLParser){
        // ここで最終処理 entries
    }


参考

[iOS] NSXMLParser で文字列が1つのエレメントで複数に分かれてパースされる
http://www.kuma-de.com/blog/2012-07-20/3782

2
4
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
2
4