23

This:

$XML = new SimpleXMLElement("<foo />");
echo($XML->asXML());

...outputs this:

<?xml version="1.0"?>
<foo/>

But I want it to output the encoding, too:

<?xml version="1.0" encoding="UTF-8"?>
<foo/>

Is there some way to tell SimpleXMLElement to include the encoding attribute of the <?xml?> tag? Aside from doing this:

$XML = new SimpleXMLElement("<?xml version='1.0' encoding='utf-8'?><foo />");
echo($XML->asXML());

Which works, but it's annoying to have to manually specify the version and encoding.

Assume for the purposes of this question that I cannot use DOMDocument instead.

dirtside
  • 8,144
  • 10
  • 42
  • 54

5 Answers5

24

You can try this, but you must use simplexml_load_string for $xml

$xml // Your main SimpleXMLElement
$xml->addAttribute('encoding', 'UTF-8');

Or you can still use other means to add the encoding to your output.

Simple Replacement

$outputXML=str_replace('<?xml version="1.0"?>', '<?xml version="1.0" encoding="UTF-8"?>', $outputXML);

Regular Expressions

$outputXML=preg_replace('/<\?\s*xml([^\s]*)\?>/' '<?xml $1 encoding="UTF-8"?>', $outputXML);

DOMDocument - I know you said you don't want to use DOMDocument, but here is an example

$xml = dom_import_simplexml($simpleXML);
$xml->xmlEncoding = 'UTF-8';
$outputXML = $xml->saveXML();

You can wrap this code into a function that receives a parameter $encoding and adds it to the

Ruben Estrada
  • 338
  • 1
  • 7
Cristian Toma
  • 5,662
  • 2
  • 36
  • 43
15

Simple and clear only do this

$XMLRoot = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><element></element>');

OutPut

<?xml version="1.0" encoding="UTF-8"?>
      <element></element>

to add attributes in element only use

$XMLRoot->addAttribute('name','juan');

to add child use

$childElement = $XMLRoot->addChild('elementChild');
$childElement->addAttribute('attribName','somthing');
DarckBlezzer
  • 4,578
  • 1
  • 41
  • 51
  • 1
    clear & easy! Thx. one hint: `$XMLRoot = new SimpleXMLElement('');` to make it even shorter – Black Senator Jul 03 '20 at 21:59
  • +1 This also works with `$xml = simplexml_load_string(' ... rest of your xml ...`. Comparing XML created in this manner, and with `Header('Content-type: text/xml;charset=utf-8'); echo $xml->asXML();`, there are no noticeable differences. – FiddlingAway Dec 07 '22 at 14:04
4

The DOMDoc proposal of Cristian Toma seems a good approach if the document isn't too heavy. You could wrap it up in something like this:

private function changeEncoding(string $xml, string $encoding) {
    $dom = new \DOMDocument();
    $dom->loadXML($xml);
    $dom->encoding = $encoding;
    return $dom->saveXML();
}

Comes in useful when you don't have access to the serializer producing the xml.

LevinM
  • 56
  • 2
1

I would say you will need to do this on creation of each XML object. Even if SimpleXMLElement had a way of setting it you would still need to set it as I guess it would be possible for the object to pick a valid default.

Maybe create a constant and Create objects like this

$XML = new SimpleXMLElement($XMLNamespace . "<foo />");
echo($XML->asXML());
Toby Allen
  • 10,997
  • 11
  • 73
  • 124
0

If you don't specify an encoding, SimpleXML cannot (sanely) guess which one you intended.

TML
  • 12,813
  • 3
  • 38
  • 45
  • I know, but the only way to specify an encoding for SimpleXML is to make it explicit in the constructor -- and then you have to specify the XML version attribute too, or it throws an error. I can obviously do it that way, it's just annoying to have to do it at all. I guess SimpleXML is a little too simple :) – dirtside May 22 '09 at 14:58
  • I can't find any reference to this in the documentation but I have the impression that you *can't* specify an encoding—because SimpleXML expects UTF-8. – Álvaro González Feb 27 '12 at 09:41