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)

Will Bond

iMarc Alumnus

Search

Recent Blog Posts

Recent Comments

  • Changes

    Jean Fitzgerald commented: Congratulations Jeff! It's a great move for you, the company will never regret it. You are one of the most creative people I know too.

  • Changes

    Claire Turcotte commented: Jeffrey! Congratulations. VERY PROUD OF YOU. Send me an answer............ Love, Memere

  • What To Know Before You SEO

    seo course bangalore commented: Wow, awesome blog layout! How long have you been blogging for? you made blogging look easy. The overall look of your website is fantastic, as well as the content! http://seocoursevideo.com/worry/

  • Changes

    Nick Hill commented: Congrats to Will and Jeff!

  • Scrolling, clicking, and the fold

    jay commented: Yeah ,,people will scroll up and down no matter what, now a days a lot of sites have horizontal scroll ..Personally i think scrolling is better than clicking..no time to waste lookin for the link and then clicking..scrolling offers all in one go.

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