Swift XMLParserでCDATAをparseをする !編集途中読まないこと!
まずCDATAとは
XMLはマークアップ言語であるため、XML文書を記述する際には、マークアップ用として指定された記号を直接文字として記述することができない。これを記述してもマークアップの指定と解釈され、文字として解釈されないためである。 しかし、マークアップ専用の記号であって、通常の文字として扱う特例的な部分をつくることができる。これを、CDATAセクションという。
CDATAセクションは、<![CDATA[という文字列で始まり、]]>という文字列で終わる。
CDATAセクションの中にはHTMLタグも埋め込むことができるので、RSSを配信している側にとっては便利。
でもXMLパーサーを回避するので、XML解析する側にとっては嫌な存在です。 ただ、XMLParserにはCDATAを解析するメソッドが用意されている。
(初心者向け)NSXMLParserでCDATAを解析する - Qiita
中身はbitコード。
ちなみにエンドポイントはこんなかんじ。
<?xml version="1.0" encoding="UTF-8"?>
螢イ荳企ォ倥′20��い繝��縲・PS縺ッ41��い繝��縺ィ縲�7縲�9譛域悄縺ョ譁ー險倬鹸繧帝#謌�
この中からtitleとid(リンク先)を取得したい。
まず普通にparseを始める。
func startDownload() { self.items = [] if let url = URL( string: "http://www.apple.com/jp/pr/feeds/pr.rss"){ //インスタンスの生成 if let parser = XMLParser(contentsOf: url) { self.parser = parser self.parser.delegate = self //これにより下記メソッドが呼ばれる self.parser.parse() } } }
ここで3つのメソッドがポイント
一つは、要素の開始ごとに呼ばれるメソッド
もう一つは、CDATAごとに呼ばれるメソッド
もう一つは、要素の終了ごとに呼ばれるメソッド
//要素の開始タグごとに呼ばれる func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) // CDATAを見つけるごとに呼ばれる エンコードする必要があり func parser(_ parser: XMLParser, foundCDATA CDATABlock: Data) { //要素の終了ごとに呼ばれるメソッド func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
エンドポイントを見ると、要素の開始タグ
var readOrNot:Bool = false //他のメンバ変数 var parser:XMLParser! var items = [Item]() var item:Item? var currentString:String?
これにより、CDATA部分で読み込むかどうかを判断させる方針とする。
これは上記要素の開始ごとに呼ばれるメソッドに記載する。
それによりCDATAの読み込み時に切り分けをする。 すべてのタグを読み込んだら大変なことになる。
if elementName == "title" || elementName == "id" { readOrNot = true