PHPでXMLを使うときの2つの注意

WordPressで記事をエクスポートするとXMLで出力されます。
これをブログ風に整形して出力しようと思ったのですが少し戸惑いました。

XML

次はエクスポートした結果です。

<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0"
  xmlns:excerpt="http://wordpress.org/export/1.2/excerpt/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wp="http://wordpress.org/export/1.2/"
>
<channel>
  <title>ブログのタイトル</title>
  <item>
    <title>記事のタイトル</title>
    <content:encoded><![CDATA[
記事の本文です。
]]></content:encoded>
    <wp:post_id>1</wp:post_id>
  </item>
  <item>
    <title>次の記事のタイトル</title>
    <content:encoded><![CDATA[
次の記事の本文です。
]]></content:encoded>
    <wp:post_id>2</wp:post_id>
  </item>
</channel>
</rss>

本物の一部を省略しています。
ファイル名を「xp.xml」とします。

PHPで取得

これをPHPで取得してみます。

$url = "wp.xml";
$content = file_get_contents($url);
$xml = simplexml_load_string($content);
print_r($xml);

「simplexml_load_string」を使っています。
これを出力すると次の通りです。

SimpleXMLElement Object
(
  [@attributes] => Array
    (
      [version] => 2.0
    )
  [channel] => SimpleXMLElement Object
    (
      [title] => ブログのタイトル
      [item] => Array
        (
          [0] => SimpleXMLElement Object
            (
              [title] => 記事のタイトル
            )
          [1] => SimpleXMLElement Object
            (
              [title] => 次の記事のタイトル
            )
        )
    )
)

「content:encoded」の部分と「wp:post_id」の部分が取得できていません。「名前空間」と言われる部分です。
また「<![CDATA[次の記事の本文です。]]>」の部分が取得できません。

2つの注意

そこで次のようにします。

$url = "wp.xml";
$content = file_get_contents($url);
$content = preg_replace("/<(.+?):(.+?)>/", "<$1_$2>", $content);
$xml = simplexml_load_string($content, "SimpleXMLElement", LIBXML_NOCDATA);
print_r($xml);

名前空間

まず名前空間については「childrenメソッドを使う」などの方法がありますが、「単純にデータを引き抜きたい」というのであれば、「content:encoded」のコロンを別の文字列に置換してしまえばOKです。
上のサンプルではタグ内の「:」を「_」に置換しています。なお「http://」も「http_//」に置換されてしまうので「.+」でなく「\w+」にするなどの工夫が必要なケースもあるかもしれません。

CDATA

CDATAセクションについては「simplexml_load_string($content, ‘SimpleXMLElement’, LIBXML_NOCDATA)」のように2番めと3番目に引数を指定してください。「LIBXML_NOCDATA」を指定することでCDATAセクションを取得できます。

出力結果

次はその出力結果です。

SimpleXMLElement Object
(
  [@attributes] => Array
    (
      [version] => 2.0
    )
  [channel] => SimpleXMLElement Object
    (
      [title] => ブログのタイトル
      [item] => Array
        (
          [0] => SimpleXMLElement Object
            (
              [title] => 記事のタイトル
              [content_encoded] =>
記事の本文です。
              [wp_post_id] => 1
            )
          [1] => SimpleXMLElement Object
            (
              [title] => 次の記事のタイトル
              [content_encoded] =>
次の記事の本文です。
              [wp_post_id] => 2
            )
        )
    )
)

コメント

  1. […] PHPでXMLを使うときの2つの注意 […]

タイトルとURLをコピーしました