我正在尝试将HTML映射到JSON中,并且保持结构不变。有没有库可以做到这一点,或者我需要编写自己的库?我想如果没有html2json库,我可以从xml2json库开始。毕竟,html只是xml的一种变体,对吧?
更新:好的,我应该举个例子。我尝试做的事情如下所示。解析html字符串:
<div>
<span>text</span>Text2
</div>
放到一个json对象中,如下所示:
{
"type" : "div",
"content" : [
{
"type" : "span",
"content" : [
"Text2"
]
},
"Text2"
]
}
备注:如果你没有注意到这个标签,我正在寻找一个解决方案
发布于 2012-10-20 08:19:46
我刚刚写了这个函数,它可以做你想做的事情;试一下,如果它不能为你正确工作,告诉我:
// 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映射的根。
发布于 2017-06-01 03:58:39
表示复杂的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')))
<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
返回正确的数据类型-这使我们更接近我们可能需要的数据类型
// 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')))
<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
发布于 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转换来添加这些元素
<?xml version="1.0" encoding="UTF-8" ?>
<type>div</type>
<content>
<type>span</type>
<content>Text2</content>
</content>
<content>Text2</content>
https://stackoverflow.com/questions/12980648
复制相似问题