Json编码或序列化XML

时间:2013-08-31 14:49:08

标签: php xml json simplexml

我有一些xml,这是它的一个简单版本。

<xml>
<items>
  <item abc="123">item one</item>
  <item abc="456">item two</item>
</items>
</xml>

在内容上使用SimpleXML,

 $obj = simplexml_load_string( $xml );

我可以使用$obj->xpath( '//items/item' );并访问@attributes。

我需要一个数组结果,所以我尝试了json_decode(json_encode($obj),true)技巧,但这似乎是要删除对@attributes的访问(即.abc =“123”)。

是否有其他方法可以实现对属性的访问,并为我提供数组?

5 个答案:

答案 0 :(得分:2)

您需要调用attributes()函数。

示例代码:

$xmlString = '<xml>
<items>
  <item abc="123">item one</item>
  <item abc="456">item two</item>
</items>
</xml>';

$xml = new SimpleXMLElement($xmlString);

foreach( $xml->items->item as $value){
$my_array[] =  strval($value->attributes());
}

print_r($my_array);

Eval

答案 1 :(得分:1)

$xml = new SimpleXMLElement($xmlString);

$ xml现在是一个对象。要获取属性的值:

$xml->something['id'];

其中'id'是属性的名称。

答案 2 :(得分:1)

您可以使用json_encodejson_decode前往路线,然后添加您遗失的内容,因为json_encode - 遵循SimpleXMLElement的某些特定规则。

如果您对规则及其详细信息感兴趣,我写了两篇关于它的博客文章:

对于你或许更有意思的是第三部分,它展示了如何修改json序列化并提供自己的格式(例如保留属性):

它附带了一个完整的例子,这里是代码的摘录:

$xml = '<xml>
<items>
  <item abc="123">item one</item>
  <item abc="456">item two</item>
</items>
</xml>';

$obj = simplexml_load_string($xml, 'JsonXMLElement');

echo $json = json_encode($obj, JSON_PRETTY_PRINT), "\n";

print_r(json_decode($json, TRUE));

JSON和数组的输出如下,请注意属性是其中的一部分:

{
    "items": {
        "item": [
            {
                "@attributes": {
                    "abc": "123"
                },
                "@text": "item one"
            },
            {
                "@attributes": {
                    "abc": "456"
                },
                "@text": "item two"
            }
        ]
    }
}
Array
(
    [items] => Array
        (
            [item] => Array
                (
                    [0] => Array
                        (
                            [@attributes] => Array
                                (
                                    [abc] => 123
                                )

                            [@text] => item one
                        )

                    [1] => Array
                        (
                            [@attributes] => Array
                                (
                                    [abc] => 456
                                )

                            [@text] => item two
                        )

                )

        )

)

答案 3 :(得分:0)

虽然理论上可以编写从XML到PHP或JSON结构的通用转换,但很难捕捉到可能存在的所有细微之处 - 子元素和属性之间的区别,文本内容与属性之间的区别(因为你有这里)或者甚至与子元素一起,具有相同名称的多个子节点,子元素和文本节点的顺序是否重要(例如在XHTML或DocBook中)等等。

如果您需要生成特定格式,使用API​​(如SimpleXML)来循环XML并生成所需的结构通常要容易得多。

您没有指定要实现的结构,但给定输入的一般方法是遍历每个项目,并访问已知属性或循环遍历每个属性:

$sxml = simplexml_load_string( $xml );
$final_array = array();
foreach ( $sxml->items->item as $xml_item )
{
    $formatted_item = array();

    // Text content of item
    $formatted_item['content'] = (string)$xml_item;

    // Specifically get 'abc' attribute
    $formatted_item['abc'] = (string)$xml_item['abc'];
    // Maybe one of the attributes is an integer
    $formatted_item['foo_id'] = (int)$xml_item['foo_id'];

    // Or maybe you want to loop over lots of possible attributes
    foreach ( $xml_item->attributes() as $attr_name => $attr_value )
    {
         $formatted_item['attrib:' . $attr_name] = (string)$attr_value;
    }

    // Add it to a final list
    $final_array[] = $formatted_item;
    // Or maybe you want that array to be keyed on one of the attributes
    $final_array[ (string)$xml_item['key'] ] = $formatted_item;
}

答案 4 :(得分:0)

这是我发现的一个类,它能够非常好地处理XML到数组:http://outlandish.com/blog/xml-to-json/backup)。转换为json是json_encode()调用的问题。