SwiftでXMLをパースする際に、
NSXMLParserを使用するのですが、以下のような要素をパースする際に
NSXMLParserを使用するのですが、以下のような要素をパースする際に
例
aaa あいうえお abcd 春夏秋冬 123
マルチバイト+アルファベット文字列が要素内であったとすると、
それぞれ分かれて、一回目aaaで二回目あいうえお、三回目abcdの形で取得できてしまって、
一気に取れないのが不便。
それぞれ分かれて、一回目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
http://www.kuma-de.com/blog/2012-07-20/3782