【问题标题】:Loop through an XML object with SimpleXML使用 SimpleXML 循环遍历 XML 对象
【发布时间】:2013-11-02 21:47:39
【问题描述】:

我正在尝试在 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 循环中使用数据。

【问题讨论】:

    标签: php xml simplexml


    【解决方案1】:

    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
            )
    
    )
    

    【讨论】:

    • 我也在以同样的方式工作,但是当我在产品中只有一件物品时它会失败。有什么解决方案吗?
    【解决方案2】:

    我不想破坏the existing answer,因为它以一般的方式回答正确。

    对于您的 concrete 要求,与您的 XML 一样,没有任何属性,您只是在这里寻找 element-name => node-value 对,这里有一个与 SimpleXMLElement 结合使用的功能: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://3v4l.org/iQKQP

    您可能会通过强制转换为数组获得类似的结果(如果与 SimpleXML 不完全相同的话),但是在这种情况下,我想映射它,我需要一个真正的函数。

    还有用于转换完整树的 json-en- 和 -de-code 加倍,这在这里也很方便:

    $xml     = simplexml_load_string($buffer);
    
    $items   = $xml->products;
    
    $devices = json_decode(json_encode($items), TRUE)['item'];
    

    然后输出与现有答案完全相同。在线演示又来了:https://3v4l.org/ToWOs

    希望这对您有所帮助并扩大视野。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-26
      • 2020-07-27
      • 2011-05-07
      • 1970-01-01
      • 1970-01-01
      • 2020-06-09
      • 2021-11-12
      • 2019-07-07
      相关资源
      最近更新 更多