nim*_*rod 58 html javascript json
我正在尝试将HTML映射到JSON,结构完整.是否有任何图书馆可以做到这一点,还是我需要自己编写?我想如果没有html2json库,我可以把xml2json库作为一个开始.毕竟,html只是xml的一个变种吗?
更新:好的,我应该举一个例子.我想要做的是以下内容.解析一串html:
<div>
<span>text</span>Text2
</div>
Run Code Online (Sandbox Code Playgroud)
像这样的json对象:
{
"type" : "div",
"content" : [
{
"type" : "span",
"content" : [
"Text2"
]
},
"Text2"
]
}
Run Code Online (Sandbox Code Playgroud)
注意:如果你没有注意到标签,我正在寻找Javascript的解决方案
Geo*_*ith 60
我刚刚编写了这个函数来做你想做的事情,尝试一下让我知道它是否对你不正常:
// 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;
}
Run Code Online (Sandbox Code Playgroud)
工作示例:http://jsfiddle.net/JUSsf/(在chrome中测试过,我无法保证完全支持浏览器 - 您必须对此进行测试).
它创建一个对象,其中包含您请求的格式的HTML页面的树结构,然后使用JSON.stringify()
它包含在大多数现代浏览器中(IE8 +,Firefox 3+ .etc); 如果您需要支持旧版浏览器,可以包含json2.js.
它可以采用一个DOM element
或一个string
包含有效的XHTML作为参数(我相信,我不确定DOMParser()
在某些情况下是否会因为设置而阻塞,"text/xml"
或者它是否只是不提供错误处理.不幸的是"text/html"
浏览器支持不佳).
您可以通过传递不同的值来轻松更改此函数的范围element
.您传递的任何值都将是您的JSON映射的根.
请享用
代表复杂的HTML文档将是困难的,并且充满了极端情况,但我只是想分享几种技术来展示如何开始这种程序.这个答案的不同之处在于它使用数据抽象和toJSON
递归构建结果的方法
下面html2json
是一个微小的函数,它将HTML节点作为输入,并返回一个JSON字符串作为结果.要特别注意代码是如何完全平坦的,但它仍然能够构建一个深度嵌套的树结构 - 所有这些都可能几乎没有复杂性
// 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')))
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
在前面的例子中,textContent
得到了一点点屠杀.为了解决这个问题,我们引入了另一个数据构造函数TextElem
.我们必须映射childNodes
(而不是children
)并选择返回正确的数据类型e.nodeType
- 这使我们更接近我们可能需要的东西
// 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')))
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
无论如何,这只是问题的两次迭代.当然,你必须解决它们出现的极端情况,但是这种方法的好处在于它为你提供了很多灵活性来编码你想要的JSON格式 - 并且没有引入太多的复杂性
根据我的经验,你可以继续使用这种技术,并取得非常好的结果.如果这个答案对任何人都很有意思,并希望我能够扩展,请告诉我^ _ ^
相关:使用JavaScript的递归方法:构建自己的JSON.stringify版本