keepcalculator

06 Numbers and Powers

Convert JSON to XML in PHP: Build the XML You Need

Card No. 06·3993 · Updated · Standard formula, shown below

To convert JSON to XML in PHP, you first decode the JSON into a PHP array or object, then iterate through that structure to build an XML document using PHP’s DOMDocument or SimpleXML. This gives you full control over the resulting XML, so you can shape it to match any schema or API requirement.

Why Convert JSON to XML in PHP?

JSON and XML are both widely used data formats, but they serve different ecosystems. JSON is lightweight and native to JavaScript, making it the default for web APIs and configuration files. XML, on the other hand, is still required in many enterprise environments, such as SOAP web services, legacy banking systems, RSS feeds, and document-centric applications like Microsoft Office files. When you need to integrate a JSON-based API with an XML-consuming system, PHP provides the tools to bridge the gap without manual copy-pasting.

The conversion is not always a one-to-one mapping. JSON has native arrays and objects, while XML relies on elements and attributes. A JSON object like {"name":"Alice"} could become <name>Alice</name> or <item name="Alice"/> depending on your needs. Understanding this distinction is the first step to building the XML you actually need.

Prerequisites and PHP Setup

Before you start, ensure your PHP environment has the necessary extensions enabled. Both DOMDocument and SimpleXML are part of the core PHP distribution, but they may need to be enabled in your php.ini file. Check with phpinfo() or run php -m in the command line to confirm. If they are missing, you can enable them by uncommenting the relevant extension= lines (e.g., extension=dom and extension=simplexml) and restarting your web server.

You also need the JSON extension, which is enabled by default since PHP 8.0. For older versions, it was a separate extension but is almost always present. If you are using Composer, there are third-party libraries like mtdowling/jmespath.php or symfony/serializer that offer more advanced conversion features, but for most cases the built-in functions are sufficient.

Method 1: Using DOMDocument for Full Control

DOMDocument gives you the most flexibility. You create an XML tree node by node, which allows you to decide whether a value becomes an element or an attribute. Here is a step-by-step example:

  1. Decode the JSON string with json_decode($json, true) to get an associative array.
  2. Create a new DOMDocument instance.
  3. Add a root element, e.g., <root>.
  4. Write a recursive function that iterates over the array. For each key-value pair, create an element. If the value is an array, recurse; otherwise, set the text content.
  5. Save the XML with $dom->saveXML().

Here is a complete code snippet:

function arrayToXml($data, &$xml) {
    foreach ($data as $key => $value) {
        if (is_array($value)) {
            if (!is_numeric($key)) {
                $subnode = $xml->addChild($key);
                arrayToXml($value, $subnode);
            } else {
                // Handle numeric keys (arrays)
                $subnode = $xml->addChild("item");
                arrayToXml($value, $subnode);
            }
        } else {
            $xml->addChild($key, htmlspecialchars($value));
        }
    }
}
$json = '{"name":"Alice","age":30,"pets":["cat","dog"]}';
$data = json_decode($json, true);
$xml = new SimpleXMLElement('<root/>');
arrayToXml($data, $xml);
echo $xml->asXML();

This produces:

<root><name>Alice</name><age>30</age><pets><item>cat</item><item>dog</item></pets></root>

Method 2: Using SimpleXML for Quick Results

SimpleXML is more concise but less flexible. It is ideal when you need a quick conversion and do not require fine-grained control over attributes or complex nesting. The same recursive approach works, but you must be careful with numeric keys because SimpleXML does not allow numeric element names. In the example above, numeric keys are converted to <item> elements.

SimpleXML also has a limitation: you cannot easily add attributes without extra code. If your target XML requires attributes (e.g., <user id="1">Alice</user>), you will need to use DOMDocument or manually add attributes via addAttribute() after creating the element.

Handling Common JSON Structures

JSON can contain nested objects, arrays, null values, and booleans. Each requires special attention:

  • Nested objects: Recursively call the conversion function, preserving the key as the element name.
  • Arrays: If the array is associative, treat it like an object. If it is a list (numeric keys), decide on a wrapper element name, like <item> or <element>.
  • Null values: In XML, a null can be represented as an empty element <key/> or with an attribute xsi:nil="true". Choose what your consumer expects.
  • Booleans: Convert true to 1 or true, and false to 0 or false. Be consistent.
  • Special characters: Always escape &, <, >, ", and ' in text content. Using htmlspecialchars() or DOMDocument’s createTextNode() handles this automatically.

Choosing Between DOMDocument and SimpleXML

The choice depends on your project’s requirements. Use DOMDocument when:

  • You need to add attributes to elements.
  • You want to control the XML declaration (e.g., encoding, standalone).
  • You are working with large documents and need memory efficiency (DOMDocument is more memory-intensive but offers more methods).
  • You need to manipulate the XML after creation (e.g., reorder nodes).

Use SimpleXML when:

  • You have a straightforward conversion with no attributes.
  • You prefer a more readable, object-oriented syntax.
  • You are converting small to medium-sized data.

Both are valid; many developers start with SimpleXML and switch to DOMDocument when they hit its limitations.

Common Pitfalls and How to Avoid Them

Here are frequent mistakes and their solutions:

  • Invalid XML element names: JSON keys may contain spaces, hyphens, or start with numbers, which are not allowed in XML element names. Sanitize keys by replacing invalid characters with underscores or using a mapping array.
  • Numeric keys: As mentioned, numeric keys are not valid element names. Use a generic name like item or entry.
  • Not escaping special characters: Forgetting to escape & or < results in malformed XML. Always use htmlspecialchars() or DOMDocument’s text node creation.
  • Empty arrays: An empty array in JSON can be ambiguous. Decide whether it should become an empty element or be omitted.
  • Encoding issues: Ensure your JSON is UTF-8. If not, convert it with mb_convert_encoding() before decoding.
  • Performance: For very large JSON files (hundreds of MB), consider streaming with json_decode in chunks or using a SAX-like parser, though this is rarely needed.

Frequently Asked Questions

Can I convert JSON to XML without writing a custom function?

Yes, there are libraries like Symfony Serializer or JMS Serializer that provide built-in JSON-to-XML conversion. However, they often require configuration to match your exact XML structure. For a one-off conversion, writing a small recursive function is simpler and more transparent.

How do I add attributes to XML elements during conversion?

Use DOMDocument. After creating an element with createElement(), call setAttribute() on it. For example, $node->setAttribute('id', $value). SimpleXML also has addAttribute(), but you must call it immediately after creating the child.

What if my JSON has a key that starts with a number?

XML element names cannot start with a digit. You can prefix the key with an underscore (e.g., _1st) or map it to a valid name like item_1. Choose a consistent strategy and document it.

Is there a way to convert JSON to XML using XSLT?

Yes, you can convert JSON to XML first (using any method), then apply XSLT to transform it further. Alternatively, some XSLT processors support JSON input directly, but this is not standard. PHP’s XSLT extension works with XML, so you would need an intermediate step.

How do I handle JSON arrays of objects?

If the array is associative (keys are strings), treat it as an object. If it is a list (numeric keys), wrap each object in a repeating element like <item>. Your recursive function should check array_keys($value) === range(0, count($value)-1) to detect a list.

Can I convert XML back to JSON in PHP?

Yes, the reverse is possible using simplexml_load_string() or DOMDocument, then recursively converting the XML tree to an array, and finally json_encode(). However, the reverse conversion is more ambiguous because XML attributes and elements have no direct JSON equivalent.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →