Pocket

名前空間やCDATAの読み込み

PHPでRSS取得するのに、単純にsimplexml_load_file()を利用して取得しようと思った時に、名前空間(「:」コロンで区切られた要素)やCDATAの値が取得できないのでメモ。 CDATAに関して言えば、取得自体はできているけど、パッと見取れていないように見えるのでちょっと工夫が必要。

WordPressの基本的なfeed(RSS2.0)を読み込む例(記事部分抜粋)

このファイルを読み込んでみます。

simplexml_load_file()で取得してみる

これだけだと、dc:creatorとcategoryが取得できません。

CDATAの取得を考える

CDATAの取得方法を考えてみました。

CDATA取得方法その1:simplexml_load_file()のパラメータを設定する

simplexml_load_file()でLIBXML_NOCDATAを第3引数に渡すことで取得できます。

libxmlはPHPのXML操作ライブラリで、その中の定義済み定数にLIBXML_NOCDATAの説明があります。他の定数も存在するので、XMLの操作をする上で一度は見ておいたほうが良いかと。

CDATA取得方法その2:CDATA要素を(string)でキャストする

CDATA要素に対して文字列として扱うように、(string)でキャストすると取得できます。

CDATA要素の数が沢山あると大変なので、「その1」のやり方がスマートのように思えます。

名前空間要素の取得を考える

次に名前空間要素の取得方法を考えてみました。

名前空間要素の取得方法その1:children()メソッドで名前空間名を指定

「:」コロンつなぎの要素、名前空間情報は、children()メソッドで指定すると取得できます。(PHPのマニュアル:SimpleXMLElement::childrenを参照)

名前空間要素の取得方法その2:記事の要素をまるごと配列に保存

これが一番やりたかった事。RSSの要素をWordPress側でカスタマイズする必要があったので、CDATAも名前空間の要素もどういうのが来るか不明なので、まるごと配列にえいやー!と保存したい。 とりあえず、何も考えずにまるごと保存してみました。

CDATAはLIBXML_NOCDATA指定により取得できました。けど、名前空間が……となったので、一度RSS情報を文字列として取得して、名前空間要素を文字列変換しパースするという方法で解決しました。

\(^o^)/取得できた!!

  1. file_get_contents()でRSS情報を取得する
  2. preg_replace()で「:」(コロン)を「_」(アンダーバー)に変換
  3. preg_replace()でプロトコルは元に戻す
  4. simplexml_load_string()で文字列XML情報をパースする

注意点

以下の2点に注意すること。

  • simplexml_load_file関数はphp.iniの設定でallow_url_fopenをOnにしていないと使えない。
  • Offの場合は、curl_get_contents()でRSS情報を取得してから、simplexml_load_string()でパースし直す。