DomDocument::loadXMLでエンコードの設定が消える件 

はてなブックマーク - DomDocument::loadXMLでエンコードの設定が消える件
Bookmark this on Delicious

さっきのjson2xmlで、phpのDomDocumentのloadXMLにハマりました。

以下がはまったサンプルコードと出力になります。

< ?php
$dom = new DomDocument('1.0', 'utf-8');
$dom->loadXML("<root><name>taichino< /name><age>25</age></name></root>");
$dom->formatOutput = true;
echo $dom->saveXML();
?>
<!-- 期待する出力 -->
< ?xml version="1.0" encoding="utf-8" ?>
<root>
  <name>taichino</name>
  <age>25</age>
</root>
 
<!-- 実際の出力 -->
< ?xml version="1.0" ?>
<root>
  <name>taichino</name>
  <age>25</age>
</root>

何故かエンコーディングの設定が消えてしまいます。環境の問題だと思い込んで、phpinfoやらphp.iniやら色々確認してみたものの何が原因か解りません。

そこで念の為以下のコードを走らせると正常の挙動を示しました。

$dom = new DomDocument('1.0', 'utf-8');
echo $dom->saveXML();
<!-- ヘッダだけだと正常に出力される -->
< ?xml version="1.0" encoding="utf-8" ?>

まさかと思いましたが、結局loadXML後にencodingを指定したら動きました。
コンストラクタでパラメータ設定できないので、loadXMLを静的呼出に合わせて変更するのが正解でしょうか。

< ?php
$dom = DomDocument::loadXML("<root><name>taichino< /name><age>25< /age>< /root>");
$dom->encoding = 'utf-8'; // ロードしてからエンコーディング設定。釈然としないけども。。
$dom->formatOutput = true;
echo $dom->saveXML();
?>
</age></name>

今回ハマった理由はphpマニュアルのloadXMLの説明に以下の記述があったからです。

このメソッドをスタティックにコールすると、読み込んだ内容をもとに DOMDocument オブジェクトを作成します。読み込み前に DOMDocument のプロパティを 設定する必要がない場合に、スタティックに実行することがあるでしょう。

いやいや、コレは読み込み前にプロパティ設定できるって思いますやん。マニュアルに騙された!

というわけで何が正しいか常に意識しながら生きていかねばなりません。思い込みで選択肢を消してはなりませぬ!

試したのはphp5.1.6と5.2.8です。既になおってたらごめんなさい。

関連する記事

タグ: ,

コメントをどうぞ