当有一个孩子时,PHP将XML转换为JSON组

Posted

技术标签:

【中文标题】当有一个孩子时,PHP将XML转换为JSON组【英文标题】:PHP convert XML to JSON group when there is one child 【发布时间】:2013-05-31 21:29:24 【问题描述】:

我使用这个 php 类将 XML 转换为 JSON:http://www.ibm.com/developerworks/library/x-xml2jsonphp/

例如对于这个 XML:

<?xml version="1.0" encoding="UTF-8"?>
<searchResult>
    <status>OK</status>
    <users>
        <user>
            <userName>johndoe</userName>
        </user>
        <user>
            <userName>johndoe1</userName>
            <fullName>John Doe</fullName>
        </user>
        <user>
            <userName>johndoe2</userName>
        </user>
        <user>
            <userName>johndoe3</userName>
            <fullName>John Doe Mother</fullName>
        </user>
        <user>
            <userName>johndoe4</userName>
        </user>
    </users>
</searchResult>

结果是:


  "searchResult": 
    "status": "OK",
    "users": 
      "user": [
         "userName": "johndoe" ,
        
          "userName": "johndoe1",
          "fullName": "John Doe"
        ,
         "userName": "johndoe2" ,
        
          "userName": "johndoe3",
          "fullName": "John Doe Mother"
        ,
         "userName": "johndoe4" 
      ]
    
  

但我想:


  "searchResult": 
    "status": "OK",
    "users": [
       "userName": "johndoe" ,
      
        "userName": "johndoe1",
        "fullName": "John Doe"
      ,
       "userName": "johndoe2" ,
      
        "userName": "johndoe3",
        "fullName": "John Doe Mother"
      ,
       "userName": "johndoe4" 
    ]
  

在“users”中分组“user”,因为这是一个只有一个孩子的数组。

我已经搜索了另一个类以将 XML 转换为 JSON 以获得此结果,但我没有找到任何资源。

你能帮我解决我的问题吗?

提前致谢,向法布里斯致以最诚挚的问候

【问题讨论】:

【参考方案1】:

您链接的文章已经过时了。例如,Services_JSON通常不再需要了。

目前稳定的 PHP 5.4 版本有 json_encode() function 和 JsonSerializable interface 以及 iterator_to_array。即使您使用的是较旧的 PHP 5.3 版本,以下示例也很容易采用。

所以你真正需要的是你自己的 SimpleXMLElement 的 JSON 编码。

首先,让我们创建“我们自己的”Json 编码器:

class XML2Json extends SimpleXMLElement


哇。那太简单了。让我们检查它是否有效:

$converter = new XML2Json($bufferXml);

echo json_encode($converter, JSON_PRETTY_PRINT), "\n";

而且结果已经和Services_JSON的结果类似:


    "status": "OK",
    "users": 
        "user": [
            
                "userName": "johndoe"
            ,
            
                "userName": "johndoe1",
                "fullName": "John Doe"
            ,
            
                "userName": "johndoe2"
            ,
            
                "userName": "johndoe3",
                "fullName": "John Doe Mother"
            ,
            
                "userName": "johndoe4"
            
        ]
    

但这不合适。如输出所示,缺少 searchResult 属性,并且用户不像您想要的那样位于单个数组中。

所以json_encode 需要用户定义。为了在 PHP 中做到这一点,PHP 具有JsonSerializable 接口。它由一个名为 jsonSerialize() 的方法组成,如果名称是 searchResult,我们现在将使它返回一个不同的值,以提供它的名称作为属性和用户作为平面数组。让我们扩展和实现接口:

class XML2JsonSearchResult extends XML2Json implements JsonSerializable


    public function jsonSerialize()
    
        $name = $this->getName();

        if ($name !== 'searchResult') 
            return $this;
        

        $value          = (array)$this;
        $value['users'] = iterator_to_array($value['users']->user, FALSE);

        return [$name => $value];
    

所有不具有名称 searchResult 的元素将通过返回 $this 来获取其默认 JSON 编码。

searchResult 将被命名,并且它的用户被 iterator_to_array() 函数展平。

这就是你需要做的。同样是用法示例,它的工作原理完全相同,只是这次类名不同:

$converter = new XML2JsonSearchResult($bufferXml);

echo json_encode($converter, JSON_PRETTY_PRINT);

现在的输出就像你想要的那样:


    "searchResult": 
        "status": "OK",
        "users": [
            
                "userName": "johndoe"
            ,
            
                "userName": "johndoe1",
                "fullName": "John Doe"
            ,
            
                "userName": "johndoe2"
            ,
            
                "userName": "johndoe3",
                "fullName": "John Doe Mother"
            ,
            
                "userName": "johndoe4"
            
        ]
    

希望这能给你一个很好的例子。

整个代码示例一目了然 (Online Demo):

class XML2JsonSearchResult extends SimpleXMLElement implements JsonSerializable


    public function jsonSerialize()
    
        $name = $this->getName();

        if ($name !== 'searchResult') 
            return $this;
        

        $value          = (array)$this;
        $value['users'] = iterator_to_array($value['users']->user, FALSE);

        return [$name => $value];
    


$converter = new XML2JsonSearchResult($bufferXml);

echo json_encode($converter, JSON_PRETTY_PRINT);

【讨论】:

感谢您的帮助。我不知道可以“格式化” json_encode 函数。所以我尝试编辑 jsonSerialize 方法以兼容我所有的 json 数据。我会在没事的时候发布它们。再次感谢,Fabrice 只是因为一些不同的问题而审查这个。您可能还需要折叠所有具有单个子元素的元素,该子元素又是一组子元素。这也可以进行测试,并且那些(如 users->user)可以自动折叠(如 users here)。

以上是关于当有一个孩子时,PHP将XML转换为JSON组的主要内容,如果未能解决你的问题,请参考以下文章

PHP - xml到json转换:“无法将字符串解析为XML”

在 PHP 中将 JSON 转换为 XML,但在 XML 中为 JSON 数组创建一个容器元素

PHP将带有一些(重复)元素的XML转换为Json到Json数组[重复]

如何停止 xslt3.0 的 xml-to-json() 函数将数字转换为指数表示法

PHP - xml 到 json 的转换:“字符串无法解析为 XML”

有没有办法通过 PHP 自动将 XML 页面转换为 JSON? [复制]