SimpleXML

SimpleXMLElement オブジェクト

コンストラクタ

final public SimpleXMLElement::__construct() (
    string $data                 // XML文字列 またはXML文書へのパス
    [, int $options = 0          // Libxmlパラメータ
    [, bool $data_is_url = false // TRUEのとき、$dataをXML文書へのパスとみなす
    [, string $ns = ""           // 名前空間 (NameSpace) プレフィックスまたはURI
    [, bool $is_prefix = false   // TRUEのとき、$nsをプレフィックスとみなす
    ]]]] )
PHP: SimpleXMLElement::__construct - Manual

SimpleXMLElementオブジェクトの生成は、SimpleXML関数からでも行えます。

メソッド

区分 メソッド 説明
要素 addChild XMLノードに子要素を追加する
children 指定したノードの子ノードを見付ける
getName XML要素の名前を取得する
count 子要素を数える
属性 addAttribute SimpleXML要素に属性を追加する
attributes 要素の属性を定義する
書式化 asXML (saveXML) SimpleXML要素に基づき整形式のXML文字列を返す
名前空間 getDocNamespaces ドキュメントで宣言されている名前空間を返す
getNamespaces ドキュメントで使用している名前空間を返す
Xpath xpath XMLデータにXpathクエリを実行する
registerXPathNamespace 次のXPathクエリ用のprefix/nsコンテキストを作成する
PHP: SimpleXMLElement - Manual

SimpleXML 関数

以下の関数はいずれも引数のデータをパースし、その結果をSimpleXMLElementオブジェクトで返します。

関数 データの種類
simplexml_import_dom DOMノード
simplexml_load_file XMLファイル (URLでも指定可)
simplexml_load_string XML文字列
PHP: SimpleXML 関数 - Manual

これらはSimpleXMLのメソッドではなく、関数です。

未定義の文字参照

データのパース時に、parser error : Entity 'copy' not definedのように警告が出ることがあります。これはXSLTで定義されていない文字参照がデータに含まれているためで、この場合ですと「© (©)」のパースに失敗しています。この問題は、もしパース対象の文書の編集が可能ならば、文字実体参照を数値文字参照に変更することで解決できます。たとえば©は、©がそれになります。

simplexml_load_file

SimpleXMLElement simplexml_load_file (
    string $filename                           // XMLファイルのパス
    [, string $class_name = "SimpleXMLElement" // 戻り値となるオブジェクトのクラス名
    [, int $options = 0                        // Libxmlパラメータ
    [, string $ns = ""                         // 名前空間プレフィックスまたはURI
    [, bool $is_prefix = false                 // nsパラメータの種類。プレフィックスならばTRUE
    ]]]] )
PHP: simplexml_load_file - Manual

simplexml_load_string

SimpleXMLElement simplexml_load_string (
    string $data
    [, string $class_name = "SimpleXMLElement"
    [, int $options = 0
    [, string $ns
    [, bool $is_prefix = false
    ]]]] )
PHP: simplexml_load_string - Manual

パースの成否の確認

パースに成功した場合にはSimpleXMLElementオブジェクトが、失敗した場合にはFALSEが返されます。このとき、

$xml = simplexml_load_string( $text );
if( $xml )
{
    // パースに成功した場合の処理
}

のようにすると、ルート要素しか持たないXML文書もパースに失敗とみなされてしまいます。これは、

<?xml version='1.0'?>
<document />

のような文書をパースすると、戻り値はメンバを持たないSimpleXMLElementオブジェクトとなり、そのようなオブジェクトは != FALSEではないためです。よって厳密な比較を用いて、

$xml = simplexml_load_string( $text );
if( $xml !== FALSE )
{
}

とする必要があります。

エラー原因の特定

エラーの詳細はlibxml_get_errors()で取得できます。

要素や属性の参照

たとえば次のようなXML文書をSimpleXMLでパースすると、

<?xml version='1.0' ?>
<movies>
  <movie>
    <title>PHP: Behind the Parser</title>
    <characters>
      <character>
        <name>Ms. Coder</name>
        <actor>Onlivia Actora</actor>
      </character>
      <character>
        <name>Mr. Coder</name>
        <actor>El Act&#211;r</actor>
      </character>
    </characters>
    <great-lines>
      <line>PHP solves all my web problems</line>
    </great-lines>
    <rating type="thumbs">7</rating>
    <rating type="stars">5</rating>
  </movie>
</movies>

結果は以下のようなオブジェクトとして返されます。

SimpleXMLElement Object
(
  [movie] => SimpleXMLElement Object
    (
      [title] => PHP: Behind the Parser
      [characters] => SimpleXMLElement Object
        (
          [character] => Array
            (
              [0] => SimpleXMLElement Object
                (
                  [name] => Ms. Coder
                  [actor] => Onlivia Actora
                )
              [1] => SimpleXMLElement Object
                (
                  [name] => Mr. Coder
                  [actor] => El ActÓr
                )
            )
        )
      [great-lines] => SimpleXMLElement Object
        (
          [line] => PHP solves all my web problems
        )
      [rating] => Array
        (
          [0] => 7
          [1] => 5
        )
    )
)

名前が同一の要素が複数ある場合には、配列としてまとめられます。

このオブジェクトが変数$xmlに格納されているとして、XMLの要素や属性へアクセスする方法を次に示します。

要素の参照

要素はオブジェクトのプロパティとして参照します。たとえば上記の<title>は、

$xml->movie->title;

で参照できます。print_r()へこのオブジェクトを渡すと、次のようにこのオブジェクトの構造を確認できます。

print_r( $xml->movie->title );

// SimpleXMLElement Object
// (
//     [0] => PHP: Behind the Parser
// )

存在しない要素を参照しようとすると、空のSimpleXMLElementオブジェクトが返されます。

取得したXMLの要素や属性は、SimpleXMLElementオブジェクトとなります。よってこれらを文字列として処理するには、(string) としてキャストする必要があります。

一方で、XPathで要素を特定する方法もあります。

print_r( $xml->xpath( 'movie/title' ) );

// Array
// (
//     [0] => SimpleXMLElement Object
//         (
//             [0] => PHP: Behind the Parser
//         )
// )

同名の複数の要素

同名の要素が複数ある場合には、配列の要素のように参照します。たとえば<character>は、

$xml->movie->characters->character[0];

で参照でき、最初の要素はそれを省いて参照できるため、

$xml->movie->characters->character;

とも記述できます。

print_r( $xml->movie->characters->character );

// SimpleXMLElement Object
// (
//     [name] => Ms. Coder
//     [actor] => Onlivia Actora
// )
print_r( $xml->xpath( 'movie/characters/character' ) );

// Array
// (
//     [0] => SimpleXMLElement Object
//         (
//             [name] => Ms. Coder
//             [actor] => Onlivia Actora
//         )
//
//     [1] => SimpleXMLElement Object
//         (
//             [name] => Mr. Coder
//             [actor] => El ActÓr
//         )
// )

命名規則に違反する名前

PHPの命名規則で使用できない文字を含む名前は、かっこと引用符で囲んで指定します。たとえば前述の<great-lines>は、

$xml->movie->{'great-lines'};

とします。<foo:b>のように名前空間の指定がある場合はまた別で、次項のように専用のメソッドを利用してアクセスします。

名前空間を指定された要素

次のように、XML名前空間を指定された要素を含む場合を考えます。

<top xmlns:foo="http://example.com">
    <a>10</a>
    <foo:b>20</foo:b>
    <foo:c>30</foo:c>
</top>

この文書を、

$xml = simplexml_load_string( $data );

でパースして、そのオブジェクトの内容をprint_r( $xml )で確認すると、

SimpleXMLElement Object
(
    [a] => 10
)

となり、名前空間が指定された要素を確認できません。このような場合にはchildren()メソッドで名前空間を指定して、

$xml->children( 'http://example.com' );

とすると、指定した名前空間に含まれる要素を、SimpleXMLElementオブジェクトとして取得できます。または

$xml->children( 'foo', TRUE );

のように、プレフィックスによる指定もできます。PHP: SimpleXMLElement::children - Manual

属性の参照

属性は連想配列として参照します。たとえば<rating type="stars">のtype属性の値を参照するには、

$xml->movie->rating[1]['type'];

とします。

@attributes

たとえば、

<foo data1="a" data2="b" />

のように、子要素を持たないが属性を持つ要素は、

[foo] => SimpleXMLElement Object
(
  [@attributes] => Array
    (
      [data1] => a
      [data2] => b
    )
)

のように取得できます。この「@attributes」で表現される属性を参照するには、

$xml->foo->attributes()->data1;

とします。