In my answer I'll cover PHP, specifically SimpleXMLElement which is already part of your code.

The basic way to JSON encode XML with SimpleXMLElement is similar to what you have in your question. You instantiate the XML object and then you json_encode it (Demo):

$xml = new SimpleXMLElement($buffer);
echo json_encode($xml, JSON_PRETTY_PRINT);

This produces an output close but not exactly like what you're looking for already. So what you do here with simplexml is that you change the standard way how json_encode will encode the XML object.

This can be done with a new subtype of SimpleXMLElement implementing the JsonSerializable interface. Here is such a class that has the default way how PHP would JSON-serialize the object:

class JsonSerializer extends SimpleXmlElement implements JsonSerializable
{
    /**
     * SimpleXMLElement JSON serialization
     *
     * @return null|string
     *
     * @link http://php.net/JsonSerializable.jsonSerialize
     * @see JsonSerializable::jsonSerialize
     */
    function jsonSerialize()
    {
        return (array) $this;
    }
}

Using it will produce the exact same output (Demo):

$xml = new JsonSerializer($buffer);
echo json_encode($xml, JSON_PRETTY_PRINT);

So now comes the interesting part to change the serialization just these bits to get your output.

First of all you need to differ between whether it's an element carrying other elements (has children) or it is a leaf-element of which you want the attributes and the text value:

    if (count($this)) {
        // serialize children if there are children
        ...
    } else {
        // serialize attributes and text for a leaf-elements
        foreach ($this->attributes() as $name => $value) {
            $array["_$name"] = (string) $value;
        }
        $array["__text"] = (string) $this;
    }

That's done with this if/else. The if-block is for the children and the else-block for the leaf-elements. As the leaf-elements are easier, I've kept them in the example above. As you can see in the else-block it iterates over all attributes and adds those by their name prefixed with "_" and finally the "__text" entry by casting to string.

The handling of the children is a bit more convoluted as you need to differ between a single child element with it's name only or multiple children with the same name which require an additional array inside:

        // serialize children if there are children
        foreach ($this as child) {
            // child is a single-named element -or- child are multiple elements with the same name - needs array
            if (count($child) > 1) {
                $child = [$child->children()->getName() => iterator_to_array($child, false)];
            }
            $array[child;
        }

Now there is another special case the serialization needs to deal with. You encode the root element name. So this routine needs to check for that condition (being the so called document-element) (compare with SimpleXML Type Cheatsheet) and serialize to that name under occasion:

    if ($this->xpath('/*') == array($this)) {
        // the root element needs to be named
        $array = [$this->getName() => $array];
    }

Finally all left to be done is to return the array:

    return $array;

Compiled together this is a JsonSerializer done in simplexml tailored to your needs. Here the class and it's invocation at once:

class JsonSerializer extends SimpleXmlElement implements JsonSerializable
{
    /**
     * SimpleXMLElement JSON serialization
     *
     * @return null|string
     *
     * @link http://php.net/JsonSerializable.jsonSerialize
     * @see JsonSerializable::jsonSerialize
     */
    function jsonSerialize()
    {
        if (count($this)) {
            // serialize children if there are children
            foreach ($this as child) {
                // child is a single-named element -or- child are multiple elements with the same name - needs array
                if (count($child) > 1) {
                    $child = [$child->children()->getName() => iterator_to_array($child, false)];
                }
                $array[child;
            }
        } else {
            // serialize attributes and text for a leaf-elements
            foreach ($this->attributes() as $name => $value) {
                $array["_$name"] = (string) $value;
            }
            $array["__text"] = (string) $this;
        }

        if ($this->xpath('/*') == array($this)) {
            // the root element needs to be named
            $array = [$this->getName() => $array];
        }

        return $array;
    }
}

$xml = new JsonSerializer($buffer);
echo json_encode($xml, JSON_PRETTY_PRINT);

Output (Demo):

{
    "foo": {
        "bar": {
            "one": [
                {
                    "_lang": "fr",
                    "_type": "bar",
                    "__text": "Test"
                },
                {
                    "_lang": "fr",
                    "_type": "foo",
                    "__text": "Test"
                },
                {
                    "_lang": "fr",
                    "_type": "baz",
                    "__text": "Test"
                }
            ]
        },
        "thunk": {
            "thud": {
                "bar": [
                    {
                        "_lang": "fr",
                        "_name": "bob",
                        "__text": "test"
                    },
                    {
                        "_lang": "bz",
                        "_name": "frank",
                        "__text": "test"
                    },
                    {
                        "_lang": "ar",
                        "_name": "alive",
                        "__text": "test"
                    },
                    {
                        "_lang": "fr",
                        "_name": "bob",
                        "__text": "test"
                    }
                ]
            }
        }
    }
}

I hope this was helpful. It's perhaps a little much at once, you find the JsonSerializable interface documented in the PHP manual as well, you can find more example there. Another example here on Stackoverflow with this kind of XML to JSON conversion can be found here: XML to JSON conversion in PHP SimpleXML.

Answer from hakre on Stack Overflow
Top answer
1 of 3
13

In my answer I'll cover PHP, specifically SimpleXMLElement which is already part of your code.

The basic way to JSON encode XML with SimpleXMLElement is similar to what you have in your question. You instantiate the XML object and then you json_encode it (Demo):

$xml = new SimpleXMLElement($buffer);
echo json_encode($xml, JSON_PRETTY_PRINT);

This produces an output close but not exactly like what you're looking for already. So what you do here with simplexml is that you change the standard way how json_encode will encode the XML object.

This can be done with a new subtype of SimpleXMLElement implementing the JsonSerializable interface. Here is such a class that has the default way how PHP would JSON-serialize the object:

class JsonSerializer extends SimpleXmlElement implements JsonSerializable
{
    /**
     * SimpleXMLElement JSON serialization
     *
     * @return null|string
     *
     * @link http://php.net/JsonSerializable.jsonSerialize
     * @see JsonSerializable::jsonSerialize
     */
    function jsonSerialize()
    {
        return (array) $this;
    }
}

Using it will produce the exact same output (Demo):

$xml = new JsonSerializer($buffer);
echo json_encode($xml, JSON_PRETTY_PRINT);

So now comes the interesting part to change the serialization just these bits to get your output.

First of all you need to differ between whether it's an element carrying other elements (has children) or it is a leaf-element of which you want the attributes and the text value:

    if (count($this)) {
        // serialize children if there are children
        ...
    } else {
        // serialize attributes and text for a leaf-elements
        foreach ($this->attributes() as $name => $value) {
            $array["_$name"] = (string) $value;
        }
        $array["__text"] = (string) $this;
    }

That's done with this if/else. The if-block is for the children and the else-block for the leaf-elements. As the leaf-elements are easier, I've kept them in the example above. As you can see in the else-block it iterates over all attributes and adds those by their name prefixed with "_" and finally the "__text" entry by casting to string.

The handling of the children is a bit more convoluted as you need to differ between a single child element with it's name only or multiple children with the same name which require an additional array inside:

        // serialize children if there are children
        foreach ($this as child) {
            // child is a single-named element -or- child are multiple elements with the same name - needs array
            if (count($child) > 1) {
                $child = [$child->children()->getName() => iterator_to_array($child, false)];
            }
            $array[child;
        }

Now there is another special case the serialization needs to deal with. You encode the root element name. So this routine needs to check for that condition (being the so called document-element) (compare with SimpleXML Type Cheatsheet) and serialize to that name under occasion:

    if ($this->xpath('/*') == array($this)) {
        // the root element needs to be named
        $array = [$this->getName() => $array];
    }

Finally all left to be done is to return the array:

    return $array;

Compiled together this is a JsonSerializer done in simplexml tailored to your needs. Here the class and it's invocation at once:

class JsonSerializer extends SimpleXmlElement implements JsonSerializable
{
    /**
     * SimpleXMLElement JSON serialization
     *
     * @return null|string
     *
     * @link http://php.net/JsonSerializable.jsonSerialize
     * @see JsonSerializable::jsonSerialize
     */
    function jsonSerialize()
    {
        if (count($this)) {
            // serialize children if there are children
            foreach ($this as child) {
                // child is a single-named element -or- child are multiple elements with the same name - needs array
                if (count($child) > 1) {
                    $child = [$child->children()->getName() => iterator_to_array($child, false)];
                }
                $array[child;
            }
        } else {
            // serialize attributes and text for a leaf-elements
            foreach ($this->attributes() as $name => $value) {
                $array["_$name"] = (string) $value;
            }
            $array["__text"] = (string) $this;
        }

        if ($this->xpath('/*') == array($this)) {
            // the root element needs to be named
            $array = [$this->getName() => $array];
        }

        return $array;
    }
}

$xml = new JsonSerializer($buffer);
echo json_encode($xml, JSON_PRETTY_PRINT);

Output (Demo):

{
    "foo": {
        "bar": {
            "one": [
                {
                    "_lang": "fr",
                    "_type": "bar",
                    "__text": "Test"
                },
                {
                    "_lang": "fr",
                    "_type": "foo",
                    "__text": "Test"
                },
                {
                    "_lang": "fr",
                    "_type": "baz",
                    "__text": "Test"
                }
            ]
        },
        "thunk": {
            "thud": {
                "bar": [
                    {
                        "_lang": "fr",
                        "_name": "bob",
                        "__text": "test"
                    },
                    {
                        "_lang": "bz",
                        "_name": "frank",
                        "__text": "test"
                    },
                    {
                        "_lang": "ar",
                        "_name": "alive",
                        "__text": "test"
                    },
                    {
                        "_lang": "fr",
                        "_name": "bob",
                        "__text": "test"
                    }
                ]
            }
        }
    }
}

I hope this was helpful. It's perhaps a little much at once, you find the JsonSerializable interface documented in the PHP manual as well, you can find more example there. Another example here on Stackoverflow with this kind of XML to JSON conversion can be found here: XML to JSON conversion in PHP SimpleXML.

2 of 3
7

I expanded on the answer by hakre. Now differentiates multiple children better. Includes attributes from entire chain except root element.

/**
 * Class JsonSerializer
 */
class JsonSerializer extends SimpleXmlElement implements JsonSerializable
{
    const ATTRIBUTE_INDEX = "@attr";
    const CONTENT_NAME = "_text";

    /**
     * SimpleXMLElement JSON serialization
     *
     * @return array
     *
     * @link http://php.net/JsonSerializable.jsonSerialize
     * @see JsonSerializable::jsonSerialize
     * @see https://stackoverflow.com/a/31276221/36175
     */
    function jsonSerialize()
    {
        $array = [];

        if ($this->count()) {
            // serialize children if there are children
            /**
             * @var string $tag
             * @var JsonSerializer $child
             */
            foreach ($this as child) {
                $temp = $child->jsonSerialize();
                $attributes = [];

                foreach ($child->attributes() as $name => $value) {
                    $attributes["$name"] = (string) $value;
                }

                $array[$tag][] = array_merge($temp, [self::ATTRIBUTE_INDEX => $attributes]);
            }
        } else {
            // serialize attributes and text for a leaf-elements
            $temp = (string) $this;

            // if only contains empty string, it is actually an empty element
            if (trim($temp) !== "") {
                $array[self::CONTENT_NAME] = $temp;
            }
        }

        if ($this->xpath('/*') == array($this)) {
            // the root element needs to be named
            $array = [$this->getName() => $array];
        }

        return $array;
    }
}
🌐
Outlandish
outlandish.com › blog › tutorial › xml-to-json
Convert XML to JSON in PHP :: Outlandish
August 23, 2012 - Here is a PHP function to do that very thing. function xmlToArray($xml, $options = array()) { $defaults = array( 'namespaceSeparator' => ':',//you may want this to be something other than a colon 'attributePrefix' => '@', //to distinguish ...
🌐
Medium
sergheipogor.medium.com › convert-xml-to-json-like-a-pro-in-php-603d0a3351f1
Convert XML to JSON Like a Pro in PHP! | by Serghei Pogor | Medium
March 21, 2024 - To achieve this, you need to develop a solution that fetches weather data from the API, converts it from XML to JSON format, and then processes and displays it within your web application’s user interface. In PHP, converting XML data to JSON format is a common task, especially when dealing with APIs or data sources that provide information in XML but need to be consumed in JSON by the application.
🌐
ItSolutionstuff
itsolutionstuff.com › post › php-convert-xml-to-json-exampleexample.html
PHP Convert XML to JSON Example - ItSolutionstuff.com
May 14, 2024 - This tutorial will give you example of php xml to json. you'll learn php convert xml to json array. This post will give you simple example of php xml to json with attributes. i would like to share with you php xml file to json.
🌐
Packagist
packagist.org › packages › extphp › xml-to-json
extphp/xml-to-json - Packagist
use ExtPHP\XmlToJson\JsonableXML; $xml = new JsonableXML('<node attr1="value1" attr2="value2"><child>child value</child></node>'); json_encode($xml); // convert xml to json // These methods are also available directly on the xml object.
🌐
Zimuel
zimuel.it › blog › xml-to-json-in-php-an-odyssey
Enrico Zimuel - XML to JSON in PHP
I decided to fix the bug ZF-3257 ... XML to JSON in PHP. My solution uses a special key value (@text) to store the text value of an XML element, only if this element contains attributes or sub-elements (as in the previous examples). If you need to convert a simple XML element with only text ...
🌐
GitHub
github.com › extphp › xml-to-json
GitHub - extphp/xml-to-json: An XML to JSON converter that will properly preserve attributes
use ExtPHP\XmlToJson\JsonableXML; $xml = new JsonableXML('<node attr1="value1" attr2="value2"><child>child value</child></node>'); json_encode($xml); // convert xml to json // These methods are also available directly on the xml object.
Author   extphp
🌐
SitePoint
sitepoint.com › blog › javascript › how to create an xml to json proxy server in php
How to Create an XML to JSON Proxy Server in PHP — SitePoint
November 6, 2024 - When you use the simplexml_load_string() function, it will include attributes in the resulting object. You can then convert this object to JSON using the json_encode() function. Some common errors you might encounter include malformed XML, encoding issues, or problems with the XML structure.
Find elsewhere
🌐
MP4Moviez
pakainfo.com › home › programming › php convert xml to json with attributes
PHP Convert XML To JSON With Attributes - Pakainfo
July 31, 2019 - {"site":[{"title":"Free Download Web Programming Courses step By step","url":"https://www.pakainfo.com/"},{"title":"tutorials point in angularjs with PHP","url":"https://www.pakainfo.com/"}]} $data_result = ' '; $xml_data = simplexml_load_string($data_result); $json_data = json_decode(json_encode($xml_data)); echo json_encode($xml_data); echo " Data is : "; echo "******************************** "; var_dump($json_data); echo "******************************** "; print_r($json_data); {"NewdatamainCat":{"firstTag":{"@attributes":{"data_val1":"false","data_val2":"true","data_val3":"false","data_va
🌐
GeeksforGeeks
geeksforgeeks.org › php › how-to-convert-xml-data-into-json-using-php
How to Convert XML data into JSON using PHP ? - GeeksforGeeks
July 23, 2025 - In this article, we are going to see how to convert XML data into JSON format using PHP.
🌐
Clue Mediator
cluemediator.com › convert-xml-to-json-in-php
Convert XML to JSON in PHP - Clue Mediator
$array = json_decode($jsonString,true); ... bk103 ) [author] => Corets, Eva [title] => Maeve Ascendant [price] => 5.95 ) ) ) Using foreach loop we can iterate each element of the associative array. foreach($array['book'] as $book){ echo $book['@attributes']['id']. ' - ' ...
🌐
GitHub
github.com › tamlyn › xml2json
GitHub - tamlyn/xml2json: XML to JSON converter in PHP
$xmlNode = simplexml_load_file('example.xml'); $arrayData = xmlToArray($xmlNode); echo json_encode($arrayData);
Starred by 49 users
Forked by 34 users
Languages   PHP 100.0% | PHP 100.0%
🌐
Fyicenter
dev.fyicenter.com › 1000592_Convert_XML_to_JSON_with_PHP.html
Convert XML to JSON with PHP
Blockchain Container EPUB General ... Phones Travel FAQ ... Currently, there is no built-in function or any standard extension that you can use to convert an XML document to a JSON text string....
🌐
Quora
quora.com › How-can-I-convert-XML-to-JSON-in-PHP
How to convert XML to JSON in PHP - Quora
Answer (1 of 5): By using just these two core features of PHP, it is possible to convert any arbitraryXML data into JSON. First, you need to convert the XML content into a suitable PHPdata type using SimpleXMLElement . Then, you feed the PHP ...
🌐
Andis Tips
andistips.com › home › php: convert xml to json
PHP: Convert XML To JSON - Andis Tips
October 20, 2019 - This file will open the XML file and interpret the files content into an object, using the simplexml_load_file() function. Next, we encode this object to JSON by using the json_encode() function and assign it to a variable named $json.
🌐
Lostechies
lostechies.com › seanbiefeld › 2011 › 10 › 21 › simple-xml-to-json-with-php
Simple XML to JSON with PHP · Los Techies
October 21, 2011 - $fileContents = trim(str_replace('"', "'", $fileContents)); $simpleXml = simplexml_load_string($fileContents); The final step we need is to convert the XML to JSON, for that we will use the _json_encode()_ function. ... <?php class XmlToJson { public function Parse ($url) { $fileContents= ...
🌐
EDUCBA
educba.com › home › software development › software development tutorials › php tutorial › php xml to json
PHP XML to JSON | Steps to Convert XML to JSON in PHP with Examples
April 4, 2023 - In order to convert XML to JSON in PHP, we have a function called json_encode function, and this is an inbuilt function in PHP and the procedure to convert XML to JSON is first getting the contents of the XML file by making use of the function ...
Address   Unit no. 202, Jay Antariksh Bldg, Makwana Road, Marol, Andheri (East),, 400059, Mumbai
🌐
php.cn
m.php.cn › home › backend development › php problem › how to convert php xml to json format
How to convert php xml to json format-PHP Problem-php.cn
May 19, 2021 - The following code demonstrates how to convert the data of an xml file into Json format data: function xmlToArray($xml, $options = array()) { $defaults = array( &#39;namespaceSeparator&#39; => &#39;:&#39;,//you may want this to be something ...