【问题标题】:How to serialize DOM node to JSON even if there are circular references?即使有循环引用,如何将 DOM 节点序列化为 JSON?
【发布时间】:2011-01-19 05:02:24
【问题描述】:

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

例如:

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

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

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

window 和 DOM 节点有很多。 window === window.windowdocument.body.ownerDocument === document 一样。

另外,JSON.stringify 不序列化函数,所以这不是我要找的。​​p>

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":"#"}}

很好,不是吗?

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

对我来说还不够好。

为什么?

我正在尝试为不同的浏览器制作 DOM 兼容性表。比如Webkit支持占位符属性而Opera不支持,IE 8支持localStorage而IE 7不支持,以此类推。

我不想制作数千个测试用例。我想用通用的方式来测试它们。

2013 年 6 月更新

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

【问题讨论】:

  • 我正在尝试为不同的浏览器制作 DOM 兼容性表。
  • 您希望如何对 DOM 节点进行序列化?你想从 DOM 节点获得什么信息?
  • Gumbo,我刚刚添加了示例。现在清楚了吗?
  • FWIW,我仍然不明白序列化为 JSON 是如何帮助您以“通用方式”测试兼容性的。
  • 我需要区分不同浏览器的整个 window 对象。如果不将window 序列化为 JSON 之类的东西,我不知道该怎么做。

标签: javascript json dom serialization circular-reference


【解决方案1】:

我找到了this,当我尝试将 XML 字符串转换为 JSON 时,它对我非常有用。

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

也许会有所帮助。

【讨论】:

  • 为了快速搜索 xmlobjectifier jquery,脚本已移至 SourceForge。但是,我发现它有点过时了。
【解决方案2】:

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>

变成

["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" ]
]

尚未使用它,但正在考虑将它用于我想要获取任何网页并使用 mustache.js 重新模板化的项目。

【讨论】:

    【解决方案3】:

    您可能会遍历 DOM 并生成它的纯 JS 对象表示,然后将其提供给 DojoX 序列化程序。但是,您必须首先决定如何将 DOM 元素、它们的属性和文本节点毫无歧义地映射到 JS 对象。例如,您将如何表示以下内容?

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

    像这样?

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

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

    【讨论】:

      【解决方案4】:

      看起来你必须自己写。 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( ... ) { ... }
      }
      ...
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-13
      • 1970-01-01
      • 2016-09-30
      • 2012-12-24
      相关资源
      最近更新 更多