Javascript 将HTML DOM结构转换为JSON
我在这件事上浪费了太多时间..递归部分很虚幻。Javascript 将HTML DOM结构转换为JSON,javascript,html,json,Javascript,Html,Json,我在这件事上浪费了太多时间..递归部分很虚幻。 对于深度未知的给定HTML结构,我需要转换为JSON。 (我使用的是我正在构建的一些YAML i18n翻译系统) 我的总体想法是深入研究,直到找到输入,然后创建一个 对象的键/值为span.innerHTML/input.value,并返回 对象,因此它将是最后到达的键的值 (是的,有点复杂,但开发起来非常有趣) -实时代码示例 我无法让递归函数正常工作,无法输出我想要的JSON… HTML结构 如果您能说服自己使用jQuery,请尝试: 我是新
对于深度未知的给定HTML结构,我需要转换为JSON。
(我使用的是我正在构建的一些YAML i18n翻译系统) 我的总体想法是深入研究,直到找到
输入
,然后创建一个
对象的键/值为span.innerHTML/input.value
,并返回
对象,因此它将是最后到达的键的值
(是的,有点复杂,但开发起来非常有趣)-实时代码示例 我无法让递归函数正常工作,无法输出我想要的JSON… HTML结构
如果您能说服自己使用jQuery,请尝试:
我是新来的,我找不到如何发表评论。我想问你,无论是哪个部门,这是否总是结构。如果答案是否定的,那么不要阅读我的答案:) 首先,我添加了一个函数getPrevious,因为直接尝试获取前一个同级会返回一个文本节点。接下来我稍微修改了递归,因为它不是一个简单的递归,json格式(父子关系)与html格式不同。我又试了两层,没问题。我希望这会有帮助,如果没有,我也很抱歉
function getPrevious(element)
{
var prev_el = element.previousSibling;
while (prev_el.nodeType == 3)
{
prev_el = prev_el.previousSibling;
}
return prev_el;
}
function recursive(element){
//var classname = element.className.split(' ');
// element.nodeName == 'UL'
var Result = {"title": '', "json": {}};
var json = {};
var cur_json_key = '';
if( element.nodeType == 3 )
return;
else{
//console.log( element.nodeType, element );
var nodeName = element.nodeName.toLowerCase();
var nodeClass = element.className.toLowerCase();
// if this is the SPAN with class 'TITLE', then create an object with the innerHTML as KEY
// and later the value should be another object, returned from the recursion...
if( nodeName == 'span' && nodeClass == 'title' ){
json[element.innerHTML] = {};
Result.title = element.innerHTML;
Result.json = json;
}
else
if( nodeName == 'input' ){
// if this is an INPUT field, then the SPAN sibling before it is the KEY.
var key = getPrevious(element).innerHTML;
var val = element.value;
Result.json[key] = val;
}
else
{
var is_title_found = 0;
var title_found = '';
var res = {}
// go deeper
for( var child=0; child < element.childNodes.length; child++ ){
//json = $.extend( {}, recursive( element.childNodes[child] ));
res = recursive( element.childNodes[child]);
if (res)
{
if (res.title != '')
{
is_title_found = 1;
title_found = res.title;
}
else
{
$.extend(true, json, res.json);
}
console.log(JSON.stringify(json));
}
}
if (title_found)
{
Result.json[title_found] = json
}
else
{
Result.json = json;
}
}
return Result;
}
}
函数getPrevious(元素)
{
var prev_el=元素.previousSibling;
while(prev_el.nodeType==3)
{
prev_el=prev_el.previousSibling;
}
返回上一页;
}
函数递归(元素){
//var classname=element.classname.split(“”);
//element.nodeName==“UL”
var Result={“title”:“”,“json”:{};
var json={};
var cur_json_key='';
if(element.nodeType==3)
返回;
否则{
//log(element.nodeType,element);
var nodeName=element.nodeName.toLowerCase();
var nodeClass=element.className.toLowerCase();
//如果这是“TITLE”类的范围,则创建一个以innerHTML为键的对象
//之后,值应该是另一个对象,从递归返回。。。
if(nodeName=='span'&&nodeClass=='title'){
json[element.innerHTML]={};
Result.title=element.innerHTML;
Result.json=json;
}
其他的
如果(节点名==“输入”){
//如果这是一个输入字段,则它前面的同级跨距是键。
var key=getPrevious(元素).innerHTML;
var val=元素值;
Result.json[key]=val;
}
其他的
{
var为\u title\u found=0;
var title_found='';
var res={}
//深入
对于(var child=0;child
- 洛勒姆
-
洛勒姆
- 洛勒姆
-
洛勒姆
-
洛勒姆
- 洛勒姆
-
洛勒姆
- 洛勒姆
- 洛勒姆
- 洛勒姆
- 洛勒姆
- 洛勒姆
var a=[];
getJSON($('in'),a);
函数getJSON(el、arr)
{
el.children().each(函数())
{
arr.push({});
arr[arr.length-1][this.tagName]=[];
if($(this.children().length>0)
{
getJSON($(this),arr[arr.length-1][this.tagName]);
}
});
}
$('#outjson').text(JSON.stringify(a));
您将获得:
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,[]}]},{“LI”:[{“DIV”:[]}]}]}]试试这个:
function helper(root) {
var result = {};
root.querySelectorAll(':scope > ul > li > span').forEach(function (obj) {
result[obj.innerText] = obj.classList.contains('title') ? helper(obj.parentNode) : obj.parentNode.querySelector('input').value;
});
return result;
}
console.log(helper(document.querySelector('body')));
缺少帮助库(如jQuery)是否是有意的?类似的用法是什么?我的意思是,这会让事情变得更容易…只是一个简短的旁注:你听说过
标签
?你应该使用它。[]非常圆滑,很好的使用。forEach.call(thing.children,function(li){
是的,无论深度如何,这都是结构。感谢你发布答案!@fortune:添加评论只能在有足够声誉的情况下完成,但你不必等待太久就能获得该代表。这是你的前10个额外;)哦,抱歉,哈哈哈
function helper(root) {
var result = {};
$('> ul > li > span', root).each(function () {
result[$(this).text()] = $(this).hasClass('title') ? helper($(this).parent()) : $(this).next('input').val();
});
return result;
}
console.log(helper('body'));
var ul = document.body.firstElementChild;
// cheat to only extract the value (key is undefined)
var data = extractKeyValue({}, ul)[1];
function extractKeyValue(span, thing) {
// return key & input value
if (thing.tagName === "INPUT") {
return [span.textContent, thing.value];
} else {
// recurse over every li and return the key/value of the span + thing
var obj = {};
[].forEach.call(thing.children, function (li) {
var span = li.firstElementChild;
var thing = span.nextElementSibling;
// tuple is [key, value]
var tuple = extractKeyValue(span, thing);
obj[tuple[0]] = tuple[1];
});
return [span.textContent, obj];
}
}
function getPrevious(element)
{
var prev_el = element.previousSibling;
while (prev_el.nodeType == 3)
{
prev_el = prev_el.previousSibling;
}
return prev_el;
}
function recursive(element){
//var classname = element.className.split(' ');
// element.nodeName == 'UL'
var Result = {"title": '', "json": {}};
var json = {};
var cur_json_key = '';
if( element.nodeType == 3 )
return;
else{
//console.log( element.nodeType, element );
var nodeName = element.nodeName.toLowerCase();
var nodeClass = element.className.toLowerCase();
// if this is the SPAN with class 'TITLE', then create an object with the innerHTML as KEY
// and later the value should be another object, returned from the recursion...
if( nodeName == 'span' && nodeClass == 'title' ){
json[element.innerHTML] = {};
Result.title = element.innerHTML;
Result.json = json;
}
else
if( nodeName == 'input' ){
// if this is an INPUT field, then the SPAN sibling before it is the KEY.
var key = getPrevious(element).innerHTML;
var val = element.value;
Result.json[key] = val;
}
else
{
var is_title_found = 0;
var title_found = '';
var res = {}
// go deeper
for( var child=0; child < element.childNodes.length; child++ ){
//json = $.extend( {}, recursive( element.childNodes[child] ));
res = recursive( element.childNodes[child]);
if (res)
{
if (res.title != '')
{
is_title_found = 1;
title_found = res.title;
}
else
{
$.extend(true, json, res.json);
}
console.log(JSON.stringify(json));
}
}
if (title_found)
{
Result.json[title_found] = json
}
else
{
Result.json = json;
}
}
return Result;
}
}
<section id="in">
<ul>
<li><div>lorem</div></li>
<li>
<div>lorem</div>
<ul>
<li><div>lorem</div></li>
<li>
<div>lorem</div>
</li>
<li>
<div>lorem</div>
<ul>
<li><div>lorem</div></li>
<li>
<div>lorem</div>
</li>
<li><div>lorem</div></li>
<li><div>lorem</div></li>
</ul>
</li>
<li><div>lorem</div></li>
</ul>
</li>
<li><div>lorem</div></li>
<li><div>lorem</div></li>
</ul>
</section>
<textarea id="outjson"></textarea>
var a = [];
getJSON($('#in'), a);
function getJSON(el, arr)
{
el.children().each(function()
{
arr.push({});
arr[arr.length-1][this.tagName] = [];
if ($(this).children().length > 0)
{
getJSON($(this), arr[arr.length-1][this.tagName]);
}
});
}
$('#outjson').text(JSON.stringify(a));
function helper(root) {
var result = {};
root.querySelectorAll(':scope > ul > li > span').forEach(function (obj) {
result[obj.innerText] = obj.classList.contains('title') ? helper(obj.parentNode) : obj.parentNode.querySelector('input').value;
});
return result;
}
console.log(helper(document.querySelector('body')));