JSON Pretty Print and JSON Multi level Collapse Code in Javascript and Python

If you are the type of programmer that deals with JSON objects a lot, you are probably familiar with some online programming tools to print out the JSON in a very “pretty” format. These tools not only make dealing with JSON easier and less frustrating but, I must admit, make it more fun too!

A “JSON viewer” app that I use regularly to “pretty-print” complicated JSON objects is at jsonviewer.stack.hu. The app has a very intuitive interface and is thus really easy to use. You can just copy a JSON object to the front page of the app or pull a JSON object from a remote location and then “format” the json. There are many more helpful JSON viewer apps and extensions that are helpful for viewing JSON.

Have you ever had the problem of trying to “pretty-print” your JSON object in your program or app for users to see, or to “collapse” your multi-level JSON object (which might contain arrays in objects and objects of arrays and …) programmatically into one level? I have certainly. Programmers that usually have these problems regularly use or make RESTFUL api calls — although RESTful “resources” can be transmitted in XML, SOAP, or even YAML, the predominant format on the web is JSON.

“JSON multi-level Collapse” Code in Javascript and Python

I cooked up the “multi-level collapse JSON” algorithm three days ago because I needed to, given a bunch of streaming JSON objects, collapse each JSON object into the most minimal form and then assemble the JSON objects into a CSV file where each JSON object occupies only one line in the CSV. Yes, my program had to first collapse any JSON object (might contain embedded objects or arrays of objects of arrays of objects of…) into a one-level JSON object without losing any information.

“Multi-level collapse” code in Javascript

// CollapseLib by Daniel Alabi (alabidan.me)
// isPlainObject is part of the jQuery source (I modified the method a little)
* Example use:
* complicated = {"dict1key": {"dict2key": [{"dict3key": {"tell":"me"}}]}}
* var dict = CollapseLib.collapseDict(collapse);
* console.log(JSON.stringify(dict, undefined, 2));
// todo: fix bug with empty plain object
var CollapseLib = {
* @warning allowed types for complexDict : {}, [], JS primitives (int, float, or string)
* @param complexDict : a JS object that might have inner JS objects and arrays OR
* a JS array that might have inner JS objects and arrays OR
* @param plainDict : a one-level collapse JS object
// if you have an empty object, just return an empty object
collapseDict : function(complexDict) {
// make plain object to return
var plainDict = {}
, sawComplex = false
, subDict;
if (CollapseLib.isPlainObject(complexDict)) {
// if complexDict is a JS object
sawComplex = false;
for (var complexKey in complexDict) {
// if complexDict[complexKey] is an inner dict
if (CollapseLib.isPlainObject(complexDict[complexKey])) {
if (CollapseLib.isEmptyObject(complexDict[complexKey])) {
return complexDict;
subDict = complexDict[complexKey];
sawComplex = true;
for (var subKey in subDict) {
plainDict[complexKey+"."+subKey] = CollapseLib.collapseDict(subDict[subKey]);
} else if (Array.isArray && Array.isArray(complexDict[complexKey])) {
if (!CollapseLib.isComplexArray(complexDict[complexKey])) {
plainDict[complexKey] = CollapseLib.getStrFromArray(complexDict[complexKey]);
} else {
sawComplex = true;
for (var i = 0; i < complexDict[complexKey].length; i++) {
plainDict[complexKey + "[" + i + "]"] = CollapseLib.collapseDict(complexDict[complexKey][i]);
} else {
plainDict[complexKey] = CollapseLib.collapseDict(complexDict[complexKey]);
if (sawComplex) {
return CollapseLib.collapseDict(plainDict);
} else {
return plainDict;
} else {
if (Array.isArray && Array.isArray(complexDict)) {
plainDict = {};
// if complexDict is an array
// that contains an inner array or inner plain object
if (CollapseLib.isComplexArray(complexDict)) {
for (var i = 0; i < complexDict.length; i++) {
plainDict["["+i+"]"] = CollapseLib.collapseDict(complexDict[i]);
return CollapseLib.collapseDict(plainDict);
} else {
return complexDict.toString();
, isComplexArray : function(arr) {
for (var i = 0; i < arr.length; i++) {
if ((Array.isArray && Array.isArray(arr[i]))
|| CollapseLib.isPlainObject(arr[i])) {
return true;
return false;
, getStrFromArray : function(arr) {
return arr.toString();
, isPlainObject: function( obj ) {
var hasOwn = Object.prototype.hasOwnProperty;
// Must be an Object.
// Because of IE, we also have to check the presence of the constructor property.
// Make sure that DOM nodes and window objects don't pass through, as well
if ( !obj || typeof obj !== "object" || obj.nodeType) {
return false;
try {
// Not own constructor property must be Object
if ( obj.constructor &&
!hasOwn.call(obj, "constructor") &&
!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
return false;
} catch ( e ) {
// IE8,9 Will throw exceptions on certain host objects #9897
return false;
// Own properties are enumerated firstly, so to speed up,
// if last one is own, then all properties are own.
var key;
for ( key in obj ) {}
return key === undefined || hasOwn.call( obj, key );
, isEmptyObject: function(obj) {
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
return false;
return true;

view raw
hosted with ❤ by GitHub

“Multi-level collapse” code in Python

# How to use:
complicated_dict = {"dict1key": {"dict2key": [{"dict3key": {"tell":"me"}}]}}
one_level_dict = makeSimpleDict(complicated_dict)
print one_level_dict
# prints out {'dict1key.dict2key.[0].dict3key.tell': u'me'}
def makeSimpleDict(complex_dict):
@param complex_dict : a python dict that might have inner dicts and arrays OR
a python list that might have inner dicts and arrays OR
a python object that's neither list of dict
@return plain_dict : plain dict that has only one level or a plain python object
# make plain dict that you will return
plain_dict = {}
if isinstance(complex_dict, dict):
# if complex_dict is a dict
# loop through the keys of this complex dict
sawComplex = False
for complex_key in complex_dict:
# if complex_dict[complex_key] is a dict
if isinstance(complex_dict[complex_key], dict):
sub_dict = complex_dict[complex_key]
# loop through the keys of this sub_dict
sawComplex = True
for sub_key in sub_dict:
plain_dict[complex_key+"."+sub_key] = makeSimpleDict(sub_dict[sub_key])
elif isinstance(complex_dict[complex_key], list):
if not isComplexList(complex_dict[complex_key]):
plain_dict[complex_key] = getStrFromList(complex_dict[complex_key])
sawComplex = True
for i in range(len(complex_dict[complex_key])):
plain_dict[complex_key+"["+str(i)+"]"] = makeSimpleDict(complex_dict[complex_key][i])
plain_dict[complex_key] = makeSimpleDict(complex_dict[complex_key])
if sawComplex:
return makeSimpleDict(plain_dict)
return plain_dict
# if not a dict
if isinstance(complex_dict, list):
# if complex_dict is a list
# is complex_dict a list
# that contains a dict or an inner list?
if not isComplexList(complex_dict):
accum = getStrFromList(complex_dict)
plain_dict = accum
# loop through the complex_dict
for i in range(len(complex_dict)):
plain_dict["["+str(i)+"]"] = makeSimpleDict(complex_dict[i])
return makeSimpleDict(plain_dict)
# if neither a list nor a dict
return unicode(complex_dict)
def isComplexList(ls):
for each in ls:
if isinstance(each, dict) or isinstance(each, list):
return True
return False
def getStrFromList(ls):
if isinstance(ls, list):
return ", ".join([unicode(each) for each in ls])
return ls

view raw
hosted with ❤ by GitHub

For example, the output of the “multi-level” algorithm on input the JSON object

{"apiVersion":"2.0","data":{"updated":"2010-01-07T19:58:42.949Z","totalItems":800,"startIndex":1,"itemsPerPage":1,"items":[{"id":"hYB0mn5zh2c","uploaded":"2007-06-05T22:07:03.000Z","updated":"2010-01-07T13:26:50.000Z","uploader":"GoogleDeveloperDay","category":"News","title":"Google Developers Day US – Maps API Introduction","description":"Google Maps API Introduction …","tags":["GDD07","GDD07US","Maps"],"thumbnail":{"default":"http://i.ytimg.com/vi/hYB0mn5zh2c/default.jpg&quot;,"hqDefault":"http://i.ytimg.com/vi/hYB0mn5zh2c/hqdefault.jpg&quot;},"player":{"default":"https://www.youtube.com/watch?v=hYB0mn5zh2c&quot;,"mobile":"https://m.youtube.com/details?v=hYB0mn5zh2c&quot;},"content":{"1":"rtsp://v5.cache3.c.youtube.com/CiILENy…/0/0/0/video.3gp&quot;,"5":"http://www.youtube.com/v/hYB0mn5zh2c?f…&quot;,"6":"rtsp://v1.cache1.c.youtube.com/CiILENy…/0/0/0/video.3gp&quot;},"duration":2840,"aspectRatio":"widescreen","likeCount":171,"rating":4.63,"ratingCount":68,"viewCount":220101,"favoriteCount":201,"commentCount":22,"status":{"value":"restricted","reason":"limitedSyndication"},"accessControl":{"syndicate":"allowed","commentVote":"allowed","rate":"allowed","list":"allowed","comment":"allowed","embed":"allowed","videoRespond":"moderated"}}]}}

view raw
hosted with ❤ by GitHub


"apiVersion": "2.0",
"data.updated": "2010-01-07T19:58:42.949Z",
"data.totalItems": "800",
"data.startIndex": "1",
"data.itemsPerPage": "1",
"data.items.[0].id": "hYB0mn5zh2c",
"data.items.[0].uploaded": "2007-06-05T22:07:03.000Z",
"data.items.[0].updated": "2010-01-07T13:26:50.000Z",
"data.items.[0].uploader": "GoogleDeveloperDay",
"data.items.[0].category": "News",
"data.items.[0].title": "Google Developers Day US – Maps API Introduction",
"data.items.[0].description": "Google Maps API Introduction …",
"data.items.[0].tags": "GDD07,GDD07US,Maps",
"data.items.[0].thumbnail.default": "http://i.ytimg.com/vi/hYB0mn5zh2c/default.jpg",
"data.items.[0].thumbnail.hqDefault": "http://i.ytimg.com/vi/hYB0mn5zh2c/hqdefault.jpg",
"data.items.[0].player.default": "https://www.youtube.com/watch?v=hYB0mn5zh2c",
"data.items.[0].player.mobile": "https://m.youtube.com/details?v=hYB0mn5zh2c",
"data.items.[0].content.1": "rtsp://v5.cache3.c.youtube.com/CiILENy…/0/0/0/video.3gp",
"data.items.[0].content.5": "http://www.youtube.com/v/hYB0mn5zh2c?f&#8230;",
"data.items.[0].content.6": "rtsp://v1.cache1.c.youtube.com/CiILENy…/0/0/0/video.3gp",
"data.items.[0].duration": "2840",
"data.items.[0].aspectRatio": "widescreen",
"data.items.[0].likeCount": "171",
"data.items.[0].rating": "4.63",
"data.items.[0].ratingCount": "68",
"data.items.[0].viewCount": "220101",
"data.items.[0].favoriteCount": "201",
"data.items.[0].commentCount": "22",
"data.items.[0].status.value": "restricted",
"data.items.[0].status.reason": "limitedSyndication",
"data.items.[0].accessControl.syndicate": "allowed",
"data.items.[0].accessControl.commentVote": "allowed",
"data.items.[0].accessControl.rate": "allowed",
"data.items.[0].accessControl.list": "allowed",
"data.items.[0].accessControl.comment": "allowed",
"data.items.[0].accessControl.embed": "allowed",
"data.items.[0].accessControl.videoRespond": "moderated"

“Pretty Print” Code in Javascript

The goal of the “Pretty Print” code is to, given a JSON object (usually used for complicated json objects that’s multi-level and really nested), print the JSON object in a very clear way so that the user sees the embedded arrays, embedded JSON objects, and embedded arrays in objects and vice versa present in the initial parent object.

So for example, the output of the “pretty print” algorithm on input the JSON object below

{"apiVersion":"2.0","data":{"updated":"2010-01-07T19:58:42.949Z","totalItems":800,"startIndex":1,"itemsPerPage":1,"items":[{"id":"hYB0mn5zh2c","uploaded":"2007-06-05T22:07:03.000Z","updated":"2010-01-07T13:26:50.000Z","uploader":"GoogleDeveloperDay","category":"News","title":"Google Developers Day US – Maps API Introduction","description":"Google Maps API Introduction …","tags":["GDD07","GDD07US","Maps"],"thumbnail":{"default":"http://i.ytimg.com/vi/hYB0mn5zh2c/default.jpg&quot;,"hqDefault":"http://i.ytimg.com/vi/hYB0mn5zh2c/hqdefault.jpg&quot;},"player":{"default":"https://www.youtube.com/watch?v=hYB0mn5zh2c&quot;,"mobile":"https://m.youtube.com/details?v=hYB0mn5zh2c&quot;},"content":{"1":"rtsp://v5.cache3.c.youtube.com/CiILENy…/0/0/0/video.3gp&quot;,"5":"http://www.youtube.com/v/hYB0mn5zh2c?f…&quot;,"6":"rtsp://v1.cache1.c.youtube.com/CiILENy…/0/0/0/video.3gp&quot;},"duration":2840,"aspectRatio":"widescreen","likeCount":171,"rating":4.63,"ratingCount":68,"viewCount":220101,"favoriteCount":201,"commentCount":22,"status":{"value":"restricted","reason":"limitedSyndication"},"accessControl":{"syndicate":"allowed","commentVote":"allowed","rate":"allowed","list":"allowed","comment":"allowed","embed":"allowed","videoRespond":"moderated"}}]}}

view raw
hosted with ❤ by GitHub


"apiVersion": "2.0",
"data": {
"updated": "2010-01-07T19:58:42.949Z",
"totalItems": 800,
"startIndex": 1,
"itemsPerPage": 1,
"items": [
"id": "hYB0mn5zh2c",
"uploaded": "2007-06-05T22:07:03.000Z",
"updated": "2010-01-07T13:26:50.000Z",
"uploader": "GoogleDeveloperDay",
"category": "News",
"title": "Google Developers Day US – Maps API Introduction",
"description": "Google Maps API Introduction …",
"tags": [
"thumbnail": {
"default": "http://i.ytimg.com/vi/hYB0mn5zh2c/default.jpg",
"hqDefault": "http://i.ytimg.com/vi/hYB0mn5zh2c/hqdefault.jpg"
"player": {
"default": "https://www.youtube.com/watch?v=hYB0mn5zh2c",
"mobile": "https://m.youtube.com/details?v=hYB0mn5zh2c"
"content": {
"1": "rtsp://v5.cache3.c.youtube.com/CiILENy…/0/0/0/video.3gp",
"5": "http://www.youtube.com/v/hYB0mn5zh2c?f&#8230;",
"6": "rtsp://v1.cache1.c.youtube.com/CiILENy…/0/0/0/video.3gp"
"duration": 2840,
"aspectRatio": "widescreen",
"likeCount": 171,
"rating": 4.63,
"ratingCount": 68,
"viewCount": 220101,
"favoriteCount": 201,
"commentCount": 22,
"status": {
"value": "restricted",
"reason": "limitedSyndication"
"accessControl": {
"syndicate": "allowed",
"commentVote": "allowed",
"rate": "allowed",
"list": "allowed",
"comment": "allowed",
"embed": "allowed",
"videoRespond": "moderated"

view raw
hosted with ❤ by GitHub

The “pretty print” code in Javascript

It’s just a simple line of JS but not many people know about how to pretty print using an already existing function in JS.

JSON.stringify(objectToPrettyPrint, undefined, 2);

view raw
hosted with ❤ by GitHub

For more information, check out the MDN Docs

Introducing Relax Accordion: Accordion with drag-and-drop and callback functionality

I’m happy to release a jQuery plugin: Relax accordion. Relax accordion was made using jQuery and some jQuery ui components, the sortable library and the droppable library.

This plugin lives on github.


You’ll need to clone this repository to use the files here.

git clone git@github.com:alabid/relaxaccordion.git

on your unix/linux command line.

To use relax accordion, you need three core js files:

  • jQuery.js — the new wave JavaScript library. The other two .js files depend on this.
  • relax.js — JavaScript file containing the implementation of the relax accordion.
  • jQuery.draggable.droppable.custom.min.js — it contains the draggable and droppable jquery ui libraries.

If you are going to use any more of the jQuery ui libraries, I’d advise that you just download and include the jQuery ui libraries you’d use with your application together with relax.js. If you do that then you wouldn’t have to include (iii) anymore. But make sure that you have the draggable, droppable, and sortable jquery ui libraries coupled with your downloads.

Download jquery ui libraries here.

After downloading (i), (ii), (iii), you can include these files in your html file like this (and preferably in this order):

 <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="jquery.draggable.droppable.custom.min.js" 

<script type=”text/javascript” src=”relax.js”></script>
<script type=”text/javascript” src=”myscript.js”

Then you can call the relax plugin in your own script like this:


The selector ul.menu specifies the list where the relax function will act upon and make a RELAX accordion.


The .relax() function takes in an object that you could use to specify some options for the relax accordion:

 // default values $("ul.menu") .relax({ "animate" : "fast", "activate-links" : false, // or "deactivate-links" : true "openondrag" : false, ondrop: function() {}, // or null opacity: 0.7 }); 

animate option specifies how fast the accordion menus should slide up or slide down. Available options: “fast”, “slow”, “normal”.

activate-links option applies to only accordion that use <a> tags in them (which is most accordions). It deactivates all the links. You can activate the links again by simply setting this option to true.

openondrag specifies if a sublist in the relax accordion menu should be open when a drag operation is being performed. If openondrag == false, then whenever you start to drag an <li> from one container to another, any open sublist closes.

ondrop is a callback that will be called whenever an <li> is moved from one sublist to another.

For example:

ondrop: function(dropped, into, contained) { log("I am "); log(dropped); log("dropped into "); log(into); log("in this menu: "); log(contained); } 

dropped is the last list item (<li>) that was dropped before the ondrop callback was called.

into is the list <ul> into which dropped was dropped into.

contained is the container/menu that encapsulates both dropped and into.


Examples of usage of relax.js are at http://vidmuster.com. Check out these ones:

  1. Two sortable accordion menus. One uses <a> elements and the other uses <p> elements in the accordion tabs. Example 1.
  2. Two sortable accordion menus that communicate with each other. You can drag from one menu to the other and also specify callbacks that will execute just immediately after you’re done moving an <li>Example 2.

Feedback, Bugs, Suggestions

I’d really like your feedback, comments, and bug reports sent to me somehow preferably by filing an issue (github feature).

HTML Parsers: The Journey to a More Semantic yet Forgiving Web

HTML5 is the next major revision of the html standard. If all works well, it should become the dominant markup in the nearest future ousting both html4 and xhtml1 from their cozy locations. A lot of people say HTML5 is the next big thing. In some sense, yes. But in another no. HTML5 isn’t another different markup language. It’s a specification that adds on to and removes some features from the already existing specifications for html4. It’s the next big thing in that it’s going to change the way we markup our html pages; it’ll add more meaning to elements making html pages more semantic. Apart from making the web more semantic html5 will also standardize a lot of features across major browsers. Finally, there’s going to be some elements that all browsers will implement and it would hopefully function the same way across these browsers. No browser will be left out including IE. Now, the ie6 death count down might even run faster. Check out the ie6 count down website at: http://www.ie6countdown.com/. Ok, that’s html5. What of xhtml1 and html4? Do they still exist and will they still exist? They still hang around and will for a while until all the browsers are standardized and old browser start to weather off.

All the html (and xhtml1) standards have parsers implemented in most non-trivial languages used frequently on the web to power web applications. There are xhtml1 and html4 parsers implemented in php, ruby, c++, and others. Most parsers use the libxml library in c to build and traverse the dom. It’s made for xml so the parser is very strict. The documentation and code for Libxml lives at: http://xmlsoft.org/. So libxml is appropriate for parsing xml but not for parsing the transitional versions of any html or xhtml. It’s not even appropriate for html5. HTML5 allows for some laxity on the side of the developer. That’s why there are parsers made specifically to parse HTML5 and no xhtml or html4 parser can appropriately parse HTML5. It’s different and COOL!!

HTML5 includes some new tags in its spec: <article>, <aside>, <header>, <section>, to mention a few. All these tags make html pages more descriptive, correspondingly making the web more semantic. These new tags will make development and deployment of web bots easier because now web bots can identify the different parts of a page and know what the data contained within the different page elements represent. They’ll now know if a writing is an article (stand-alone), if it’s just tangentially related to it’s surrounding content, if it’s a header section, and even how to outline the headers (using hgroup), and so on. For more information on the semantics of the new html5 tags and their use, please see Dive into HTML5. I think it’s a really practical and non-trivial guide to the new and emerging HTML5 specification. These new tags alone could throw the already existing parsers for html4 and xhtml off the edge. But there’s more complication to the work html5 parsers must handle. HTML5 is so FORGIVING! The <head>, <html>, and <body> tags which were required in the previous html specifications are now IMPLIED! That means that your web html5 page need not use these pivotal tags at all. You can have a page that looks like this:

<li>My boy is coming

The above markup is represented the same way in dom as this:
<body><li>My boy is coming</li>

It seems like a mess but it’s not. Since every page will have to have these tags why not just help the author of the page define those tags as the page is read into the DOM? HTML5 parsers have to handle this situation. Soon, you’ll see how the HTML5 parsers handle these weirdo syntax.

HTML5 parsing has been detailed by the WHATWG group to help authors of HTML5 parsers build effective parsers. The group explains how to parse html5 documents. This document is very important to html parser authors and should be used progressively since the html5 specification is still changing (will not fixed for some time I assure you). This document is so detailed. It veers into the input stream and even the character encodings that the html5 parser should be able to handle. That’s why it didn’t take long for html5 parsers to spring up. One prominent suite of html5 parsers implemented in multiple languages is the HTML5lib. There are currently python, php, and ruby implementations available for download. Only the python version, though, is still being actively developed. The ruby version is dead while the php version is still in it’s alpha release state, I think. On the other hand, the html5lib has been ported to javascript/node.js. But this seems to be an event-driven parser. So it might be a SAX (Simple API for XHML) and not a DOM parser (which most people use). The SAX Model is more compatible with node.js since node.js is also event-driven. But event-driven parsers usually stop when malformed syntax is encountered. Errors discourage html authors who most of the time don’t know what the standard is (might change tomorrow). And there’s another port for java programmers (expected, right?); it’s called Validator.nu HTML parser and it contains SAX, DOM, XOM API’s (jack of all trades). There’s no port to functional languages like clojure yet. Awwww… Maybe I’ll port it to clojure.

You might ask: what about HTML5 validation? HTML5 validation isn’t really necessary anymore due to the most forgiving syntax of HTML5. What’s there to validate when your page does not even need a root tag?

Some time ago, I was playing with some HTML Parsers and comparing how these parsers handle malformed html syntax. My tests were entirely written in php. I fed some malformed syntax to DOMDocument, HTML5lib, and the php simple dom parser. The PHP simple dom parser is basically the DOMDocument PHP parser on steroids. The Simple dom parser allows for easy traversal of the dom. For example, suppose, that you want to find all the image elements in an HTML page. Using DOMDocument library in php, you would write something like document.getElementsByTagName("img"); which returns a NodeList of the image Nodes in the DOM representation of your just created html document. Using the simple html dom, you can do this: $html->find('img') where $html is the root of your document as in document.documentElement == $html

I cannot show all but some part of the whole rundown and results of tests I ran on the html parsers. I wouldn’t show you in exact terms either. I had some strings containing some well-formed html4-transitional, xhtml-transitional, html5 as well as malformed versions of the aforementioned markups.

$first = "<html>
<h1>My First Heading</h1>
<p>My first paragraph.</p>
$second = "<li>Tell me all about ya!";
$third = "<body>
<p>I was with you</p>

Then I ran these html markup through the html5 parser and the DOMDocument library in PHP like this:

$dom1 = new DOMDocument("1.0", "utf-8");
$dom1->formatOutput = true;
$dom1->loadXML($first); // did the same thing for $second and $third
echo $dom1->saveXML();
echo "\n";

The above code creates a DOMDocument in XML so the $first and $third html strings pass the test since they are both
valid xml but the $second is malformed. Complains that the <li> tag  isn’t matched by its closing tag.

$dom3 = DOMImplementation::createDocument(null, 'html',
"-//W3C//DTD XHTML 1.0 Transitional//EN",
$dom3->formatOutput = true;

$html = $dom3->documentElement;
// set up $html strings
$html->loadHTML($first); // did the same for $second and $third too.
echo $html->saveHTML();

The above snippet creates a document in xhtml1 transitional.
$first is valid xhtml1
$second — helps close the <li> tag
$third — valid xhtml1 transitional. Puts a <html>  tag but no <head>  tag present.

$dom2 = DOMImplementation::createDocument(null, 'html',
"-//W3C//DTD HTML 4.01 Transitional//EN",
$dom2->formatOutput = true;

$html = $dom2->documentElement;
// set up $html strings
$html->loadHTML($first); // did the same for $second and $third too.
echo $html4_document->saveHTML();

The above snippet creates a document in html4 transitional.
$first is valid.
$second – since it’s transitional it just helps close the <li> tag
$third – puts the <html> (root) element in the dom but does not put the <head> element. Valid html4 transitional

$dom1 = HTML5_Parser::parse($first); // do the same for $
echo $dom1->saveHTML();
echo "\n";

The above snippet uses the HTML5 parser to parse the html strings: $first, $second, $third.
$first , $second, $third passes.
It closes the <li> tag as needed and puts in the <html>, <head>,<body> elements in the DOM when absent.

The tests I ran were a more than this and more complex. I stripped some details to make the tests I ran easier to comprehend. Plus, I ran it on the command line. That’s why I use new lines to demarcate individual tests instead of <br> tags.

So we love html5. It’s forgiving. It’s modern. It might eventually replace flash. It’s already on our iphones and smart phones and is implemented in all recent versions of major browsers (including ie). We don’t need to validate our pages again because we know the built-in browser parsers won’t spew out errors (good or bad thing? You be the judge…). We can start using it right away even on older browsers (we can just use modernizr and HTML5shivs to detect if some html5 features are present in a browser). There are tools out there to help us handle old browser! Ain’t that great? We’ve already started our tortuous journey to a more semantic yet forgiving web!