PHP convert XML to JSON group when there is one child

后端 未结 1 697
予麋鹿
予麋鹿 2020-11-30 15:56

I use this PHP class to convert XML to JSON:http://www.ibm.com/developerworks/library/x-xml2jsonphp/

For example for this XML:



        
相关标签:
1条回答
  • 2020-11-30 16:13

    The article you've linked is pretty outdated. For example Services_JSON is normally not needed any longer.

    The stable PHP 5.4 version right now has json_encode() function and the JsonSerializable interface as well as iterator_to_array. Even if you're using the older PHP 5.3 version, the following example is pretty easy to adopt.

    So what you actually need is your own JSON encoding of a SimpleXMLElement.

    So first of all, let's just create "our own" Json encoder:

    class XML2Json extends SimpleXMLElement
    {
    }
    

    Wow. That was dead simple. Let's check that it works:

    $converter = new XML2Json($bufferXml);
    
    echo json_encode($converter, JSON_PRETTY_PRINT), "\n";
    

    And the result is already similiar to the result with Services_JSON:

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

    But this is not fitting. As the output shows, the searchResult property is missing and also the users are not in a single array like you want them.

    So the json_encode needs to be user-defined. To do this in PHP, PHP has the JsonSerializable interface. It consists of a single method named jsonSerialize() and we will make it return a different value now if the name is searchResult to offer both it's name as property and the users as a flat array. Let's extend and implement the interface:

    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];
        }
    }
    

    All elements that don't have the name searchResult will get their default JSON encoding by returning $this.

    The searchResult will be named and it's users are flattened by the iterator_to_array() function.

    And that is all you need to do. Again the usage-example, it works exactly the same, only this time the class-name differs:

    $converter = new XML2JsonSearchResult($bufferXml);
    
    echo json_encode($converter, JSON_PRETTY_PRINT);
    

    And the output now is like you want it:

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

    Hope this gives you a good example how to do it nowadays.

    The whole code-example at a glance (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);
    
    0 讨论(0)
提交回复
热议问题