51

The title pretty much says it all.

If I have something like (from PHP site examples):

$xmlstr = <<<XML
<?xml version='1.0' standalone='yes'?>
<movies></movies>
XML;

$sxe = new SimpleXMLElement($xmlstr);

$sxe->addAttribute('type', 'documentary');

$movie = $sxe->addChild('movie');
$movie->addChild('title', 'PHP2: More Parser Stories');
$movie->addChild('plot', 'This is all about the people who make it work.');

$characters = $movie->addChild('characters');
$character  = $characters->addChild('character');
$character->addChild('name', 'Mr. Parser');
$character->addChild('actor', 'John Doe');

$rating = $movie->addChild('rating', '5');
$rating->addAttribute('type', 'stars');


echo("<pre>".htmlspecialchars($sxe->asXML())."</pre>");

die();

I end up outputing a long string like so:

<?xml version="1.0" standalone="yes"?>
<movies type="documentary"><movie><title>PHP2: More Parser Stories</title><plot>This is all about the people who make it work.</plot><characters><character><name>Mr. Parser</name><actor>John Doe</actor></character></characters><rating type="stars">5</rating></movie></movies>

This is fine for a program consumer, but for debugging/human tasks, does anyone know how to get this into a nice indented format?

Cave Johnson
  • 6,499
  • 5
  • 38
  • 57
Eli
  • 97,462
  • 20
  • 76
  • 81

3 Answers3

81

There's a variety of solutions in the comments on the PHP manual page for SimpleXMLElement. Not very efficient, but certainly terse, is a solution by Anonymous

$dom = dom_import_simplexml($simpleXml)->ownerDocument;
$dom->formatOutput = true;
echo $dom->saveXML();

The PHP manual page comments are often good sources for common needs, as long as you filter out the patently wrong stuff first.

Mat
  • 202,337
  • 40
  • 393
  • 406
Adam Wright
  • 48,938
  • 12
  • 131
  • 152
  • 2
    per comment by @karka91 in ['original question'](http://stackoverflow.com/a/799792/1037948), you must declare the `DOMDocument`+config before importing the xml, hence [this](http://stackoverflow.com/a/16282331/1037948) working instead – drzaus Jul 15 '14 at 15:55
65

The above didn't work for me, I found this worked:

$dom = new DOMDocument("1.0");
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($simpleXml->asXML());
echo $dom->saveXML();
Bidders
  • 651
  • 5
  • 3
  • 8
    You should change the last line (the `echo`) to: `echo "
    ".htmlentities($dom->saveXML())."
    ";`
    – MirroredFate Jun 12 '14 at 22:25
  • 4
    I'm using this and had no need for the pre tags when outputting the correct headers for the content type. header('Content-type: text/xml'); – Ryan Rentfro Jul 12 '15 at 15:41
  • 4
    @MirroredFate You are making it look like XML in a browser but you're outputting HTML... What if OP uses CLI PHP? What if OP wants to output to a file? – RockTheShow Sep 22 '15 at 09:55
  • @RyanRentfro Either the HTTP server or your browser is automatically adding the preamble (ctrl+u is actually page source after browser parsing). That doesn't mean you shouldn't specify it cleanly in the first place. – RockTheShow Sep 22 '15 at 09:55
  • @Léo In OP's question he wraps the output in `
    ` tags, which indicated to me that he was outputting it to a browser. But you're right, if your stdout was cli, you wouldn't want/need `pre` tags.
    – MirroredFate Sep 22 '15 at 16:15
9

Found a similar solution...to format raw xlm data..from my php SOAP requests __getLastRequest & __getLastResponse, for quick debugging the xml's i have combined it with google-code-prettify.

Its a good solution if you want to format sensitive xml data and don't want to do it online.

Some sample code below, may be helpful to others:

$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($data); //=====$data has the raw xml data...you want to format

echo '<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>';

echo "<br/> <pre class=\"prettyprint\" >". htmlentities($dom->saveXML())."</pre>";

Below is a sample of the Formatted XML Output I got:

Note: The formatted XML is available in $dom->saveXML() and can be directly saved to a xml file using php file write.

Formatted XML Output

naxrohan
  • 352
  • 3
  • 15
  • to skip `SOAP-ENV:Envelope` and `SOAP-ENV:Body` tags I used `$dom->saveXML($dom->firstChild->firstChild->firstChild)` I know it's not cool, anyway it's just prettifying for debug purposes – vladkras Oct 27 '16 at 12:20