web-dev-qa-db-ja.com

SimpleXMLを使用してXMLオブジェクトをループします

PHPでSimpleXMLを使用してXMLオブジェクトをループしようとしています-オブジェクト形式は次のとおりです:-

要素タグを名前で取得しようとすると、次のエラーが発生します-誰かが私が間違っていることを説明できますか?

Call to undefined method SimpleXMLElement::getElementsByTagName() on ...

以下は私が読んでいるXMLファイルです:

<?xml version="1.0" encoding="utf-8"?>
<response>
    <products>
        <item>
            <product_id>32417</product_id>
            <manufacturer>Alcatel</manufacturer>
            <model>Sparq 2</model>
            <deeplink>http://www.mysite.com/sc_offer?gid=32417</deeplink>
            <thumbnail_URL>http://www.mysite.com/images/devices/thumbs/Alcatel-Sparq-II.jpg</thumbnail_URL>
            <image_URL>http://www.mysite.com/images/devices/Alcatel-Sparq-II.jpg</image_URL>
            <price_not_working>0.00</price_not_working>
            <price_poor>0.00</price_poor>
            <price_fair>20.00</price_fair>
            <price_good>25.00</price_good>
            <price_perfect>25.00</price_perfect>
            <price_new>25.00</price_new>
            <battery_new>1.00</battery_new>
            <battery_perfect>1.00</battery_perfect>
            <battery_good>1.00</battery_good>
            <battery_fair>1.00</battery_fair>
            <battery_poor>0.00</battery_poor>
            <charger_new>1.00</charger_new>
            <charger_perfect>1.00</charger_perfect>
            <charger_good>1.00</charger_good>
            <charger_fair>1.00</charger_fair>
            <charger_poor>0.00</charger_poor>
            <packaging_new>1.00</packaging_new>
            <packaging_perfect>1.00</packaging_perfect>
            <packaging_good>1.00</packaging_good>
            <packaging_fair>1.00</packaging_fair>
            <packaging_poor>0.00</packaging_poor>
        </item>
        <item>
            <product_id>31303</product_id>
            <manufacturer>Apple</manufacturer>
            <model>iPhone 3G 8gb</model>
            <deeplink>http://www.mysite.com/sc_offer?gid=31303</deeplink>
            <thumbnail_URL>http://www.mysite.com/images/devices/thumbs/iPhone 8 3G.jpg</thumbnail_URL>
            <image_URL>http://www.mysite.com/images/devices/iPhone 8 3G.jpg</image_URL>
            <price_not_working>0.00</price_not_working>
            <price_poor>0.00</price_poor>
            <price_fair>7.00</price_fair>
            <price_good>2.00</price_good>
            <price_perfect>2.00</price_perfect>
            <price_new>2.00</price_new>
            <battery_new>1.00</battery_new>
            <battery_perfect>1.00</battery_perfect>
            <battery_good>1.00</battery_good>
            <battery_fair>1.00</battery_fair>
            <battery_poor>0.00</battery_poor>
            <charger_new>1.00</charger_new>
            <charger_perfect>1.00</charger_perfect>
            <charger_good>1.00</charger_good>
            <charger_fair>1.00</charger_fair>
            <charger_poor>0.00</charger_poor>
            <packaging_new>1.00</packaging_new>
            <packaging_perfect>1.00</packaging_perfect>
            <packaging_good>1.00</packaging_good>
            <packaging_fair>1.00</packaging_fair>
            <packaging_poor>0.00</packaging_poor>
        </item>
    </products>
</response>

私のPHPコードは以下のとおりです:

$devices = $xml->getElementsByTagName( "response" ); // error on this line

Foreachループでデータを使用できるように、デバイスを配列にしようとしています。

6
Zabs

SimpleXMLにはgetElementsByTagName()メソッドがありません(DOMDocumentにはあります)。

SimpleXMLでは、オブジェクト(例:$xml)はルート要素として扱われます。したがって、次のように製品アイテムをループできます。

$xml = simplexml_load_string($xmlString);
foreach($xml->products->item as $item)
{
    echo (string)$item->product_id;
    echo (string)$item->model;
}

デバイス連想配列の構築例:

$devices = array();

$xml = simplexml_load_string($xmlString);
foreach($xml->products->item as $item)
{
   $device = array();

   foreach($item as $key => $value)
   {
        $device[(string)$key] = (string)$value;
   }

   $devices[] = $device;
}

print_r($devices);

出力:

Array
(
    [0] => Array
        (
            [product_id] => 32417
            [manufacturer] => Alcatel
            [model] => Sparq 2
            [deeplink] => http://www.mysite.com/sc_offer?gid=32417
            [thumbnail_URL] => http://www.mysite.com/images/devices/thumbs/Alcatel-Sparq-II.jpg
            [image_URL] => http://www.mysite.com/images/devices/Alcatel-Sparq-II.jpg
            [price_not_working] => 0.00
            [price_poor] => 0.00
            [price_fair] => 20.00
            [price_good] => 25.00
            [price_perfect] => 25.00
            [price_new] => 25.00
            [battery_new] => 1.00
            [battery_perfect] => 1.00
            [battery_good] => 1.00
            [battery_fair] => 1.00
            [battery_poor] => 0.00
            [charger_new] => 1.00
            [charger_perfect] => 1.00
            [charger_good] => 1.00
            [charger_fair] => 1.00
            [charger_poor] => 0.00
            [packaging_new] => 1.00
            [packaging_perfect] => 1.00
            [packaging_good] => 1.00
            [packaging_fair] => 1.00
            [packaging_poor] => 0.00
        )

    [1] => Array
        (
            [product_id] => 31303
            [manufacturer] => Apple
            [model] => iPhone 3G 8gb
            [deeplink] => http://www.mysite.com/sc_offer?gid=31303
            [thumbnail_URL] => http://www.mysite.com/images/devices/thumbs/iPhone 8 3G.jpg
            [image_URL] => http://www.mysite.com/images/devices/iPhone 8 3G.jpg
            [price_not_working] => 0.00
            [price_poor] => 0.00
            [price_fair] => 7.00
            [price_good] => 2.00
            [price_perfect] => 2.00
            [price_new] => 2.00
            [battery_new] => 1.00
            [battery_perfect] => 1.00
            [battery_good] => 1.00
            [battery_fair] => 1.00
            [battery_poor] => 0.00
            [charger_new] => 1.00
            [charger_perfect] => 1.00
            [charger_good] => 1.00
            [charger_fair] => 1.00
            [charger_poor] => 0.00
            [packaging_new] => 1.00
            [packaging_perfect] => 1.00
            [packaging_good] => 1.00
            [packaging_fair] => 1.00
            [packaging_poor] => 0.00
        )

)
33
MrCode

私は台無しにしたくない 既存の答え それは一般的な方法で正しい答えをしているので。

XMLの場合と同様に、concrete要件の場合、属性はなく、要素を探しているだけです。 -name => node-valueのペアはここにあり、SimpleXMLElementと組み合わせて頭に浮かぶ関数が1つあります: get_object_vars

オブジェクトを配列に変換するときはいつでも便利です。SimpleXMLElementは要素名をオブジェクトのプロパティ名に変換し、ノード値をそれらのプロパティ値として変換するので、ここでは非常に簡単です。

$xml     = simplexml_load_string($buffer);

$items   = $xml->products->item;

$devices = array_map('get_object_vars', iterator_to_array($items, FALSE));

print_r($devices);

出力は、既存の回答で提案されているとおりです。そして、オンラインデモはここにあります: https://eval.in/57109

配列にキャストしても同様の結果が得られる可能性がありますが(SimpleXMLとまったく同じではない場合)、この場合、マップしたかったので、真の関数が必要でした。

完全なツリーを変換するためのjson-en-および-de-codeダブリングもあります。これはここでも役立ちます。

$xml     = simplexml_load_string($buffer);

$items   = $xml->products;

$devices = json_decode(json_encode($items), TRUE)['item'];

その場合、出力は既存の回答とまったく同じになります。そして、オンラインデモもここにあります: https://eval.in/57117

これがお役に立てば、ビューが少し広がります。

3
hakre