Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to serialize DOM node to JSON even if there are circular references?

I want to serialize DOM node or even whole window to JSON.

For example:

 >> serialize(document)     -> {       "URL": "http://stackoverflow.com/posts/2303713",       "body": {         "aLink": "",         "attributes": [           "getNamedItem": "function getNamedItem() { [native code] }",           ...         ],         ...         "ownerDocument": "#" // recursive link here       },       ...     } 

JSON.stringify()

JSON.stringify(window) // TypeError: Converting circular structure to JSON 

The problem is JSON does not support circular references by default.

var obj = {} obj.me = obj JSON.stringify(obj) // TypeError: Converting circular structure to JSON 

window and DOM nodes have many of them. window === window.window as will as document.body.ownerDocument === document.

Also, JSON.stringify does not serialize functions, so this is not what I'm looking for.

dojox.json.ref

 `dojox.json.ref.toJson()` can easily serialize object with circular references:      var obj = {}     obj.me = obj     dojox.json.ref.toJson(obj); // {"me":{"$ref":"#"}} 

Good, isn't it?

 dojox.json.ref.toJson(window) // Error: Can't serialize DOM nodes 

Well not good enough for me.

Why?

I'm trying to make DOM compatibility table for different browsers. For instance, Webkit supports placeholder attribute and Opera doesn't, IE 8 supports localStorage and IE 7 doesn't, and so on.

I don't want to make thousands of test-cases. I want to make generic way for test them all.

Update, June 2013

I made a prototype NV/dom-dom-dom.com.

like image 870
NVI Avatar asked Feb 20 '10 21:02

NVI


People also ask

How can you avoid converting circular structure to JSON?

The "Converting circular structure to JSON" error occurs when we pass an object that contains circular references to the JSON. stringify() method. To solve the error, make sure to remove any circular references before converting the object to JSON.

What is circular reference JSON?

Kelly M. - September 28, 2020. A circular structure is an object that references itself. In the example below, we are referencing the object (obj) as a value for the location key.

How do I Stringify a DOM element?

Here is the code : var container = document. querySelectorAll('. container') var json=JSON. stringify(container) {"0":{},"1":{},"2":{},"3":{}}"//result expected result: {"tagname":"div","class":"container","value":"test","childelement":[...]}

What JavaScript method is used to serialize a JSON object?

JSON supports plain objects, arrays, strings, numbers, booleans, and null . JavaScript provides methods JSON. stringify to serialize into JSON and JSON. parse to read from JSON.


2 Answers

http://jsonml.org/ takes a shot at a grammar for converting XHTML DOM elements into JSON. An an example:

<ul>     <li style="color:red">First Item</li>     <li title="Some hover text." style="color:green">Second Item</li>     <li><span class="code-example-third">Third</span> Item</li> </ul> 

becomes

["ul",     ["li", {"style": "color:red"}, "First Item"],     ["li", {"title": "Some hover text.", "style": "color:green"}, "Second Item"],     ["li", ["span", {"class": "code-example-third"}, "Third"], " Item" ] ] 

Haven't used it yet, but thinking about using it for a project where I want to take any web page and re-template it using mustache.js.

like image 181
Josh Dzielak Avatar answered Sep 21 '22 23:09

Josh Dzielak


You could potentially traverse the DOM and generate a pure JS object representation of it and then feed it to the DojoX serializer. But, you have to first decide how you're planning to map DOM elements, their attributes and the text nodes, without ambiguity, to JS objects. For example, how would you represent the following?

<parent attr1="val1">   Some text   <child attr2="val2"><grandchild/></child> </parent> 

Like this?

{     tag: "parent",     attributes: [         {             name: "attr1",             value: "val1"         }     ],     children: [         "Some text",         {             tag: "child",             attributes: [                 {                     name: "attr2",                     value: "val2"                 }             ],             children: [                 { tag: "grandchild" }             ]          }      ]  } 

I think the a reason DojoX doesn't immediately support DOM serialization could exactly be this: The need to first pick a scheme for mapping DOM to JS objects. Is there a standard scheme that could be employed? Would your JS object simply mimic a DOM tree without any functions? I think you have to first define what your expectation is from "serializing DOM to JSON".

like image 45
Ates Goral Avatar answered Sep 24 '22 23:09

Ates Goral