如何将DOM节点序列化为JSON,即使有循环引用?

时间:2021-07-11 16:57:17

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

我想将DOM节点甚至整个窗口序列化为JSON。

For example:

例如:

 >> serialize(document)
    -> {
      "URL": "http://*.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.

问题是JSON默认不支持循环引用。

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.

窗口和DOM节点有许多这样的节点。= = =窗口的窗口。窗口和document.body一样。ownerDocument = = =文档。

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

此外,JSON。stringify不序列化函数,所以这不是我要找的。

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.

我正在尝试为不同的浏览器创建DOM兼容性表。例如,Webkit支持占位符属性,Opera不支持,IE 8支持localStorage, IE 7不支持,等等。

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.

我做了一个原型NV/dom-dom-dom.com。

4 个解决方案

#1


13  

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

http://jsonml.org/尝试将XHTML DOM元素转换为JSON的语法。一个例子:

<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.

还没有使用过它,但是考虑过将它用于一个项目,在这个项目中,我想使用任何web页面并使用mustache.js重新对其进行模板化。

#2


5  

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?

您可以遍历DOM并生成它的纯JS对象表示,然后将其提供给DojoX序列化器。但是,您必须首先决定如何规划DOM元素、它们的属性和文本节点,而不需要对JS对象进行模糊处理。例如,如何表示以下内容?

<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".

我认为DojoX不立即支持DOM序列化的原因可能是:需要首先选择一种将DOM映射到JS对象的方案。有没有一个标准的方案可以采用?您的JS对象会简单地模拟一个没有任何函数的DOM树吗?我认为您必须首先定义您的期望是什么,从“序列化DOM到JSON”。

#3


4  

I found this and it worked great for me when I was trying to convert an XML string into JSON.

我发现这一点,当我试图将XML字符串转换为JSON时,它对我来说非常有用。

XMLObjectifier.xmlToJSON(XMLObjectifier.textToXML(xmlString));

Maybe it will help.

也许会有所帮助。

#4


3  

It looks like you have to write it on your own. JSON serialized data may also not be the perfect choice for your task (DOM compatibility table). You probably have to iterate the objects on your own, check types of the attributes and so on..

看起来你得自己写。JSON序列化数据可能也不是您的任务(DOM兼容性表)的最佳选择。您可能需要自己迭代对象,检查属性的类型等等。

var functions = [];
var strings = [];
for( var key in window ) {
    if( typeof window[key] == 'string' ) {
        strings[strings.length] = key;
    } else if( typeof window[key] == 'function' ) {
        functions[functions.length] = key;
    } else if( ... ) { ... }
}
...

#1


13  

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

http://jsonml.org/尝试将XHTML DOM元素转换为JSON的语法。一个例子:

<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.

还没有使用过它,但是考虑过将它用于一个项目,在这个项目中,我想使用任何web页面并使用mustache.js重新对其进行模板化。

#2


5  

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?

您可以遍历DOM并生成它的纯JS对象表示,然后将其提供给DojoX序列化器。但是,您必须首先决定如何规划DOM元素、它们的属性和文本节点,而不需要对JS对象进行模糊处理。例如,如何表示以下内容?

<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".

我认为DojoX不立即支持DOM序列化的原因可能是:需要首先选择一种将DOM映射到JS对象的方案。有没有一个标准的方案可以采用?您的JS对象会简单地模拟一个没有任何函数的DOM树吗?我认为您必须首先定义您的期望是什么,从“序列化DOM到JSON”。

#3


4  

I found this and it worked great for me when I was trying to convert an XML string into JSON.

我发现这一点,当我试图将XML字符串转换为JSON时,它对我来说非常有用。

XMLObjectifier.xmlToJSON(XMLObjectifier.textToXML(xmlString));

Maybe it will help.

也许会有所帮助。

#4


3  

It looks like you have to write it on your own. JSON serialized data may also not be the perfect choice for your task (DOM compatibility table). You probably have to iterate the objects on your own, check types of the attributes and so on..

看起来你得自己写。JSON序列化数据可能也不是您的任务(DOM兼容性表)的最佳选择。您可能需要自己迭代对象,检查属性的类型等等。

var functions = [];
var strings = [];
for( var key in window ) {
    if( typeof window[key] == 'string' ) {
        strings[strings.length] = key;
    } else if( typeof window[key] == 'function' ) {
        functions[functions.length] = key;
    } else if( ... ) { ... }
}
...