php 使用 SimpleXML 遍历 XML 对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19561657/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 19:42:30  来源:igfitidea点击:

Loop through an XML object with SimpleXML

phpxmlsimplexml

提问by Zabs

I am trying to use SimpleXML in PHP to loop through a XML object - the object format is below:-

我正在尝试在 PHP 中使用 SimpleXML 来遍历 XML 对象 - 对象格式如下:-

I get the following error when I try to get the element tags by name - can anyone explain what I am doing wrong?

当我尝试按名称获取元素标签时出现以下错误 - 谁能解释我做错了什么?

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

Below is the XML file I am reading from:

下面是我正在阅读的 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>

My PHP code is below:

我的PHP代码如下:

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

I am trying to make devices an array so I can use the data in a foreach loop.

我正在尝试使设备成为一个数组,以便我可以在 foreach 循环中使用数据。

回答by MrCode

SimpleXML doesn't have a getElementsByTagName()method (DOMDocument does).

SimpleXML 没有getElementsByTagName()方法(DOMDocument 有)。

In SimpleXML, the object (e.g $xml) is treated as the root element. So you can loop through the product items like so:

在 SimpleXML 中,对象(例如$xml)被视为根元素。所以你可以像这样循环遍历产品项目:

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

Example of building a devices associative array:

构建设备关联数组的示例:

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

Outputs:

输出:

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
        )

)

回答by hakre

I don't want to spoil the existing answeras it is answering correct an in a general fashion.

我不想破坏现有答案,因为它以一般方式回答正确。

For your concreterequirements as with your XML there aren't any attributes and you're just looking for the element-name => node-valuepairs here, there is one function that comes to mind in conjunction with SimpleXMLElement here: get_object_vars.

为了您的具体要求与XML没有任何属性,而你只是为了寻找元素名称=>节点-值对在这里,有自带与的SimpleXMLElement结合想到这里一个功能:get_object_vars

It is useful whenever you convert an object into an array and as SimpleXMLElement turns element names into object property names and the node-values as those property values it's pretty straight forward here:

每当您将对象转换为数组并且 SimpleXMLElement 将元素名称转换为对象属性名称和节点值作为这些属性值时,它非常有用,这里非常简单:

$xml     = simplexml_load_string($buffer);

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

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

print_r($devices);

The output is as suggested in the existing answer. And the online demo is here: https://eval.in/57109.

输出与现有答案中的建议相同。在线演示在这里:https: //eval.in/57109

You will likely able to achieve similar results with casting to arrays (if not exactly the same with SimpleXML), however in this case as I wanted to map it, I needed a true function.

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

There is also the json-en- and -de-code doubling for converting complete trees, which comes in handy here, too:

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

$xml     = simplexml_load_string($buffer);

$items   = $xml->products;

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

The output then again is exactly as the existing answer. And the online demo again is here: https://eval.in/57117

然后输出与现有答案完全相同。在线演示再次在这里:https: //eval.in/57117

Hope this is helpful and widens the view a bit.

希望这会有所帮助,并稍微拓宽视野。