循环通过SimpleXML对象,或将整个事物转换为数组

时间:2009-05-16 01:22:13

标签: php amazon-web-services simplexml amazon-simpledb

我正在尝试研究如何通过返回的SimpleXML对象进行迭代。

我正在使用一个名为Tarzan AWS的工具包,它连接到Amazon Web Services(SimpleDB,S3,EC2等)。我特意使用SimpleDB。

我可以将数据放入Amazon SimpleDB服务中,我可以将其恢复。我只是不知道如何处理返回的SimpleXML对象。

Tarzan AWS文档说明了这一点:

  

查看响应以浏览响应的标题和正文。请注意,这是一个对象,而不是一个数组,并且正文是一个SimpleXML对象。

以下是返回的SimpleXML对象的示例:

 [body] => SimpleXMLElement Object
        (
            [QueryWithAttributesResult] => SimpleXMLElement Object
                (
                    [Item] => Array
                        (
                            [0] => SimpleXMLElement Object
                                (
                                    [Name] => message12413344443260
                                    [Attribute] => Array
                                        (
                                            [0] => SimpleXMLElement Object
                                                (
                                                    [Name] => active
                                                    [Value] => 1
                                                )

                                            [1] => SimpleXMLElement Object
                                                (
                                                    [Name] => user
                                                    [Value] => john
                                                )

                                            [2] => SimpleXMLElement Object
                                                (
                                                    [Name] => message
                                                    [Value] => This is a message.
                                                )

                                            [3] => SimpleXMLElement Object
                                                (
                                                    [Name] => time
                                                    [Value] => 1241334444
                                                )

                                            [4] => SimpleXMLElement Object
                                                (
                                                    [Name] => id
                                                    [Value] => 12413344443260
                                                )

                                            [5] => SimpleXMLElement Object
                                                (
                                                    [Name] => ip
                                                    [Value] => 10.10.10.1
                                                )

                                        )

                                )

                            [1] => SimpleXMLElement Object
                                (
                                    [Name] => message12413346907303
                                    [Attribute] => Array
                                        (
                                            [0] => SimpleXMLElement Object
                                                (
                                                    [Name] => active
                                                    [Value] => 1
                                                )

                                            [1] => SimpleXMLElement Object
                                                (
                                                    [Name] => user
                                                    [Value] => fred
                                                )

                                            [2] => SimpleXMLElement Object
                                                (
                                                    [Name] => message
                                                    [Value] => This is another message
                                                )

                                            [3] => SimpleXMLElement Object
                                                (
                                                    [Name] => time
                                                    [Value] => 1241334690
                                                )

                                            [4] => SimpleXMLElement Object
                                                (
                                                    [Name] => id
                                                    [Value] => 12413346907303
                                                )

                                            [5] => SimpleXMLElement Object
                                                (
                                                    [Name] => ip
                                                    [Value] => 10.10.10.2
                                                )

                                        )

                                )

                        )

那么我需要通过哪些代码来浏览每个对象项?我想循环遍历它们并像返回的mySQL查询一样处理它。例如,我可以查询SimpleDB,然后通过SimpleXML循环,这样我就可以在页面上显示结果。

或者,你如何将整个shebang变成一个阵列?

我是SimpleXML的新手,所以如果我的问题不够具体,我会道歉。

6 个答案:

答案 0 :(得分:17)

您可以在SimpleXML循环中使用foreach对象(或其属性)。如果你想循环遍历所有'记录',可以使用这样的东西来访问和显示数据:

//Loop through all the members of the Item array 
//(essentially your two database rows).
foreach($SimpleXML->body->QueryWithAttributesResult->Item as $Item){
    //Now you can access the 'row' data using $Item in this case 
    //two elements, a name and an array of key/value pairs
    echo $Item->Name;
    //Loop through the attribute array to access the 'fields'.
    foreach($Item->Attribute as $Attribute){
        //Each attribute has two elements, name and value.
        echo $Attribute->Name . ": " . $Attribute->Value;
    }
}

请注意,$ Item将是一个SimpleXML对象,因为它是$ Attribute,因此需要将它们作为对象引用,而不是数组。

虽然上面的示例代码循环遍历SimpleXML对象中的数组($ SimpleXML-> body-> QueryWithAttributesResult-> Item),但您也可以遍历SimpleXML对象(比如$ SimpleXML-> body) - > QueryWithAttributesResult-> Item [0]),这将为您提供每个对象的属性。

SimpleXML对象的每个子元素都是XML实体。如果XML实体(标记)不是唯一的,则该元素只是表示每个实体的SimpleXML对象数组。

如果你愿意,这应该从你的SimpleXML对象创建一个更常见的行/字段数组(或让你关闭):

foreach($SimpleXML->body->QueryWithAttributesResult->Item as $Item){
    foreach($Item->Attribute as $Attribute){
        $rows[$Item->Name][$Attribute->Name] = $Attribute->Value;
    }
}

//Now you have an array that looks like:
$rows['message12413344443260']['active'] = 1;
$rows['message12413344443260']['user'] = 'john';
//etc.

答案 1 :(得分:8)

get_object_vars($simpleXMLElement);

答案 2 :(得分:5)

为PHP 5.2修复添加了一点点。

$response_array = json_decode(json_encode($response),true);

答案 3 :(得分:2)

如果XML响应不包含CDATA部分(如Amazon的/ Tarzan),则可以使用以下假设您拥有PHP 5.2或更高版本。

// Get a SimpleXML response back from Tarzan
$s3 = new AmazonS3();
$response = $s3->list_buckets();

// Convert SimpleXML to Array in PHP 5.2.
$response_array = json_decode(json_encode($response));

这将是下一个主要版本的Tarzan(CloudFusion 2.5)中所有对象可用的标准实用程序。

答案 4 :(得分:0)

我发现的几乎所有示例都涉及一个已经知道节点的特定示例。 以下函数会将SimpleXMLElement转换为数组,而无需知道节点名称或它们是否具有子节点。在CDATA部分中也可以正常工作。

function parseXML(SimpleXMLElement $xml) : array
{
    $array = [];

    foreach(iterator_to_array($xml, TRUE) as $key => $value)
        $array[$key] = ($value->count() > 1) ? parseXML($value) : (string)$value;

    return $array;
}

答案 5 :(得分:-2)

这有效:

// $result is a Simple XML object

$result = convertSimpleXMLToArray($result);

function convertSimpleXMLToArray($xml)
{
    if(class_basename($xml) == 'SimpleXMLElement')
    {
        $xml = get_object_vars($xml);
        foreach($xml as $key => $value)
        {
            if(class_basename($value) == 'SimpleXMLElement') $xml[$key] = convertSimpleXMLToArray($value);
        }
    }

    return $xml;
}