首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >将HTML映射到JSON

将HTML映射到JSON
EN

Stack Overflow用户
提问于 2012-10-20 02:52:35
回答 5查看 116.8K关注 0票数 73

我正在尝试将HTML映射到JSON中,并且保持结构不变。有没有库可以做到这一点,或者我需要编写自己的库?我想如果没有html2json库,我可以从xml2json库开始。毕竟,html只是xml的一种变体,对吧?

更新:好的,我应该举个例子。我尝试做的事情如下所示。解析html字符串:

代码语言:javascript
复制
<div>
  <span>text</span>Text2
</div>

放到一个json对象中,如下所示:

代码语言:javascript
复制
{
  "type" : "div",
  "content" : [
    {
      "type" : "span",
      "content" : [
        "Text2"
      ]
    },
    "Text2"
  ]
}

备注:如果你没有注意到这个标签,我正在寻找一个解决方案

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-10-20 08:19:46

我刚刚写了这个函数,它可以做你想做的事情;试一下,如果它不能为你正确工作,告诉我:

代码语言:javascript
复制
// Test with an element.
var initElement = document.getElementsByTagName("html")[0];
var json = mapDOM(initElement, true);
console.log(json);

// Test with a string.
initElement = "<div><span>text</span>Text2</div>";
json = mapDOM(initElement, true);
console.log(json);

function mapDOM(element, json) {
    var treeObject = {};
    
    // If string convert to document Node
    if (typeof element === "string") {
        if (window.DOMParser) {
              parser = new DOMParser();
              docNode = parser.parseFromString(element,"text/xml");
        } else { // Microsoft strikes again
              docNode = new ActiveXObject("Microsoft.XMLDOM");
              docNode.async = false;
              docNode.loadXML(element); 
        } 
        element = docNode.firstChild;
    }
    
    //Recursively loop through DOM elements and assign properties to object
    function treeHTML(element, object) {
        object["type"] = element.nodeName;
        var nodeList = element.childNodes;
        if (nodeList != null) {
            if (nodeList.length) {
                object["content"] = [];
                for (var i = 0; i < nodeList.length; i++) {
                    if (nodeList[i].nodeType == 3) {
                        object["content"].push(nodeList[i].nodeValue);
                    } else {
                        object["content"].push({});
                        treeHTML(nodeList[i], object["content"][object["content"].length -1]);
                    }
                }
            }
        }
        if (element.attributes != null) {
            if (element.attributes.length) {
                object["attributes"] = {};
                for (var i = 0; i < element.attributes.length; i++) {
                    object["attributes"][element.attributes[i].nodeName] = element.attributes[i].nodeValue;
                }
            }
        }
    }
    treeHTML(element, treeObject);
    
    return (json) ? JSON.stringify(treeObject) : treeObject;
}

工作示例:http://jsfiddle.net/JUSsf/ (在Chrome上测试过,我不能保证完全支持浏览器--你必须对此进行测试)。

它创建一个对象,其中包含您要求的格式的超文本标记语言页面的树形结构,然后使用JSON.stringify(),这是包括在大多数现代浏览器(IE8+,火狐3+ .etc);如果你需要支持旧的浏览器,你可以包括json2.js

它可以接受DOM元素或包含有效XHTML的string作为参数(我相信,我不确定DOMParser()在某些情况下是否会阻塞,因为它被设置为"text/xml",或者它只是不提供错误处理。不幸的是,"text/html"对浏览器的支持很差)。

通过将不同的值作为element传递,可以很容易地更改此函数的范围。您传递的任何值都将是JSON映射的根。

票数 85
EN

Stack Overflow用户

发布于 2017-06-01 03:58:39

表示复杂的HTML文档将是困难的,并且充满了转折点,但我只想分享几个技术来展示如何启动这类程序。这个答案的不同之处在于它使用数据抽象和toJSON方法来递归地构建结果

下面,html2json是一个很小的函数,它接受一个HTML节点作为输入,并返回一个JSON字符串作为结果。特别要注意代码是如何相当扁平的,但它仍然有足够的能力构建深度嵌套的树结构-所有这些都可以以几乎零的复杂性实现

代码语言:javascript
复制
// data Elem = Elem Node

const Elem = e => ({
  toJSON : () => ({
    tagName: 
      e.tagName,
    textContent:
      e.textContent,
    attributes:
      Array.from(e.attributes, ({name, value}) => [name, value]),
    children:
      Array.from(e.children, Elem)
  })
})

// html2json :: Node -> JSONString
const html2json = e =>
  JSON.stringify(Elem(e), null, '  ')
  
console.log(html2json(document.querySelector('main')))
代码语言:javascript
复制
<main>
  <h1 class="mainHeading">Some heading</h1>
  <ul id="menu">
    <li><a href="/a">a</a></li>
    <li><a href="/b">b</a></li>
    <li><a href="/c">c</a></li>
  </ul>
  <p>some text</p>
</main>

在前面的示例中,textContent有点被破坏了。为了解决这个问题,我们引入了另一个数据构造函数TextElem。我们必须在childNodes (而不是children)上进行映射,并选择基于e.nodeType返回正确的数据类型-这使我们更接近我们可能需要的数据类型

代码语言:javascript
复制
// data Elem = Elem Node | TextElem Node

const TextElem = e => ({
  toJSON: () => ({
    type:
      'TextElem',
    textContent:
      e.textContent
  })
})

const Elem = e => ({
  toJSON : () => ({
    type:
      'Elem',
    tagName: 
      e.tagName,
    attributes:
      Array.from(e.attributes, ({name, value}) => [name, value]),
    children:
      Array.from(e.childNodes, fromNode)
  })
})

// fromNode :: Node -> Elem
const fromNode = e => {
  switch (e.nodeType) {
    case 3:  return TextElem(e)
    default: return Elem(e)
  }
}

// html2json :: Node -> JSONString
const html2json = e =>
  JSON.stringify(Elem(e), null, '  ')
  
console.log(html2json(document.querySelector('main')))
代码语言:javascript
复制
<main>
  <h1 class="mainHeading">Some heading</h1>
  <ul id="menu">
    <li><a href="/a">a</a></li>
    <li><a href="/b">b</a></li>
    <li><a href="/c">c</a></li>
  </ul>
  <p>some text</p>
</main>

无论如何,这只是问题的两次迭代。当然,您必须解决出现的特殊情况,但是这种方法的好处是,它为您提供了很大的灵活性,可以在JSON中以您希望的方式对HTML进行编码-而不会引入太多的复杂性

根据我的经验,你可以继续使用这种技术进行迭代,并获得非常好的结果。如果有人对这个答案感兴趣,并希望我对任何东西进行扩展,请让我知道^_^

相关:Recursive methods using JavaScript: building your own version of JSON.stringify

票数 12
EN

Stack Overflow用户

发布于 2012-10-20 03:19:06

当我读到JSON框架本身就是ExtJS时,我得到的链接很少。

http://www.thomasfrank.se/xml_to_json.html

http://camel.apache.org/xmljson.html

在线XML转换器:http://jsontoxml.utilities-online.info/

更新JSON,为了获得所添加的,HTML中也需要有类型和内容标签,或者您需要在执行JSON转换时使用一些xslt转换来添加这些元素

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8" ?>
<type>div</type>
<content>
    <type>span</type>
    <content>Text2</content>
</content>
<content>Text2</content>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12980648

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档