【问题标题】:PHP convert XML to JSON group when there is one child当有一个孩子时,PHP将XML转换为JSON组
【发布时间】: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 以获得此结果,但我没有找到任何资源。

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

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

【问题讨论】:

    标签: php xml json simplexml converter


    【解决方案1】:

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

    目前稳定的 PHP 5.4 版本有 json_encode() functionJsonSerializable 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)。
    猜你喜欢
    • 2018-03-21
    • 1970-01-01
    • 2014-12-24
    • 2012-02-08
    • 2018-07-30
    • 2015-09-07
    • 1970-01-01
    • 2017-11-04
    • 2011-11-03
    相关资源
    最近更新 更多