XML Pretty Printer in PHP5

Today I was working with debugging some XML, and needed a way to make the XML more readable. The following is a little function that should do the job for some simple XML, and you can probably tweak it to your needs. It uses PHP5's SimpleXMLElement object to parse and return the XML, then indents it in a logical way.

Comments

Friday, May 16, 2008 / 8:54am Phoenix said…

Nice work man, pretty easy to tweak too. I got it just right to my job.

Cheers.

Monday, Jul 7, 2008 / 4:38pm WheeGuy said…

Thank you for the cute function, it saved me some time. For very linear responses (ie, no newlines) give this a shot:

1. Replace the explode's separator with '><' 2. Replace the join's separator with "> <"

Monday, Oct 13, 2008 / 3:33pm anon said…

In response to the above poster's comment:

Good start, but nothing seems to get indented like that. Maybe this is a better fix...

Replace line 16 (the line beginning with "$xml_lines") with the following:

$xml_lines = explode(" ", str_replace("><", "> <", $xml_obj->asXML()));

That's it =)

Monday, Oct 13, 2008 / 3:36pm anon said…

oops, line 12, not 16. And imagine backslash-Ns where those line breaks are (either will work).

Thursday, Oct 30, 2008 / 2:15pm Fred Trotter said…

After much fighting... I have included both the improvements from the comments above, and a trick that allows your xml pretty print function to work when xml is included in other xml which is what happens when there is an XML arguement to a soap call.

This makes your function work well against the results of SoapClient::__getLastResponse and SoapClient::__getLastRequest

This will save me a lot of time being able to directly read debug output from __getLastResponse and __getLastRequest

May this help the next googler.

function xml_pretty_printer($xml, $html_output=FALSE) { $xml_obj = new SimpleXMLElement($xml); $xml_lines = explode("\n", str_replace("><",">\n<",$xml_obj->asXML())); $indent_level = 0; $new_xml_lines = array(); foreach ($xml_lines as $xml_line) { if (preg_match('#^(<[a-z0-9_:-]+((s+[a-z0-9_:-]+="[^"]+")*)?>.*]+>)|(<[a-z0-9_:-]+((s+[a-z0-9_:-]+="[^"]+")*)?s*/s*>)#i', ltrim($xml_line))) { $new_line = str_pad('', $indent_level*4) . ltrim($xml_line); $new_xml_lines[] = $new_line; } elseif (preg_match('#^<[a-z0-9_:-]+((s+[a-z0-9_:-]+="[^"]+")*)?>#i', ltrim($xml_line))) {

$new_line = str_pad('', $indent_level*4) . ltrim($xml_line); $indent_level++; $new_xml_lines[] = $new_line; } elseif (preg_match('#/]+>#i', $xml_line)) { $indent_level--; if (trim($new_xml_lines[sizeof($new_xml_lines)-1]) == trim(str_replace("/", "", $xml_line))) { $new_xml_lines[sizeof($new_xml_lines)-1] .= $xml_line; } else { $new_line = str_pad('', $indent_level*4) . $xml_line; $new_xml_lines[] = $new_line; } } else { $new_line = str_pad('', $indent_level*4) . $xml_line; $new_xml_lines[] = $new_line; } } $xml = join("\n", $new_xml_lines); return ($html_output) ? '

' . $this->xmlspecialchars($xml) . '

' : $xml; }

function xmlspecialchars($text) { return str_replace(''', ''', htmlspecialchars($text, ENT_QUOTES, 'UTF-8',false)); }

Thursday, Oct 30, 2008 / 8:30pm Ray said…

Hey Fred,

In your last example, the whitespace tokens in the regexes are missing backslashes, resulting in indenting errors where entities have attributes. Replace 's' with 's' in those, and it's all good. :-)

Thursday, Oct 30, 2008 / 8:31pm Ray said…

Aaarrrggghhh... looks like backslashes are being stripped from posts (twice?), resulting in backslashes being removed from the comments.

Wednesday, Nov 26, 2008 / 4:43pm Kirk, the Next Googler said…

Thanks - I've been helped! Work's great after touching up the regex's.

Comments have been turned off on this blog.
Read something more recent.

Statements and opinions expressed in this blog and any comments made are the private opinions of the respective poster, and, as such, iMarc LLC is neither responsible nor liable for such content.

Meet The Author

Will Bond

Director of Engineering, Technical Architect

Search

Recent Blog Posts

Recent Comments

  • Cutting the Content Clutter

    legal high us highs commented: hello there and thanks to your info ? I have definitely picked up something new from right here. I did alternatively experience several technical points using this web site, as I experienced to reload the web site a lot of instances previous to I could get it to load correctly. I have been thinking about if your web hosting is OK?…

  • I LOLed

    Bill Keeshen commented: Nils, Love the site, congrats! You have a spirited culture as well! Regards, Bill

  • Changing Tradition (for the better)

    Nick commented: This is a fantastic and charitable idea! I would agree, purchasing from and donating to 2 local businesses is a win! Great job iMarc!

  • Content, Content, Content

    dano commented: Totally agree, once I start updating content on a regular basis I start seeing direct and repeat traffic increase exponentially! dano

  • I LOLed

    Pat McNally commented: Hi Nils, I have to be in NY this year for your 12/8 party (great invite), but wish I could be with you. I gave the invite to my 28 year old daughter, Jen Breaker, and urged her to stop in to say hi for me. I hope you and your family have a wonderful and exciting Christmas and holidays. Do you remember what I was doing on New…

We heart Visitors

  • iMarc
  • 14 Inn Street
  • Newburyport, MA 01950
  • Phone: (978) 462-8848
  • Fax: (978) 462-8807
  • Directions

Contact Us

Whether you have a huge project or just want to talk about updating your site, we’re here to help. Fill out the form, and we’ll get right back to you.

Contact Us
  • All Fields Required

Close