如何使用jQuery将HTML树转换为自定义的JSON树?

4
<ul id='parent_of_all'>
<li>
  <span class='operator'>&&</span>
  <ul>
    <li>
      <span class='operator'>||</span>
      <ul>
        <li>
          <span class='operator'>&&</span>
          <ul>
            <li>
            <span class='condition'>1 == 1</span>
            </li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
  <ul>
    <li>
      <span class='condition'>1 != 0</span>
    </li>
  </ul>
</li>
</ul>

为了

{"&&":[{'||':[ {'&&':[ {"lhs": "1", "comparator": "==", "rhs":"1"} ]} ] } , {"lhs": "1", "comparator": "!=", "rhs":"0"}]}

目前我了解jQuery、JavaScript的基础知识。为了完成上述转换,需要知道从何处开始思考。

而且html树可能会更加复杂,包含更多子元素。

3个回答

1
您可以使用 eachmap 来实现此操作。

var obj = {}
var span = $('li > span').not('ul li span').text();

$('ul li span').each(function() {
 var text = $(this).text().split(' ');
 obj[span] = (obj[span]||[]).concat({lhs: text[0], comparator: text[1], rhs: text[2]});
});

console.log(obj)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li>
  <span>&&</span>
  <ul>
    <li>
      <span>1 == 1</span>
    </li>
  </ul>
  <ul>
    <li>
      <span>1 != 0</span>
    </li>
  </ul>
</li>


你的实现与Alexandru的相同,仅限于一级树。因此,如果我在第n级添加一个子节点,你的代码会将其附加到根父节点而不是直接父节点。 - bill_cosby

1
你需要一种选择第一层 li 的方法,我假设你有一个带有 id 的父元素,例如 list。我使用基本的 jQuery 编写了以下代码,以便你可以理解它。
var result = {};

var $all_li = $('#list').children('li');     // selecting the first level of li
for(var i in $all_li){                       // iterating all_li using for (you may use forEach )  

    var $current_li = $( $all_li[i] );                       // getting operator from first span
    var operator = $current_li.children('span').html();      // the text of the operator

    var $inner_spans = $current_li.find('>ul >li >span');    // getting list of children spans (from path $list>li>ul>li>span)
    var li_spans = [];                                       // an array where we will put the inner span objects
    for(var j in $inner_spans){ // iterating the inner spans
        var text = $($inner_spans[j]).html().split(" ");     // splitting the html
        li_spans.push({
            lhs: text[0],
            comparator: text[1],
            rhs: text[2]
        });                                // adding the splitted html to an object. Note: error if text didn't have 2 white spaces
    }

    result[operator] = li_spans;          // adding the operator key and li_spans value to the result json
}

这段代码将解析HTML并构建result JSON,它应该适用于您提供的HTML格式。请注意,它不处理错误(例如错误的树格式)和类似的HTML格式。

感谢您的开始。但是您的实现仅限于一级树。因此,如果我在第n级添加一个子项,您的代码将附加到根父项而不是直接父项。 - bill_cosby
@bill_cosby,您提供了一个非常具体的HTML结构,从您的示例中我们无法理解结果应该是什么样子。 - Alexandru Severin
抱歉,但我确实提到了树可能会很复杂。我刚刚进行了编辑。 - bill_cosby

0

感谢 @Alexandru 和 @Nenad 给了一个开端。我已经能够独立完成这个任务了。 以下是生成JSON的函数。

function prepare_json(current_node){
    var object = {}
    var span = $(current_node).children('span')
    if (span.hasClass('condition')){
        var text = span.html().split(" ");
        object = {lhs: text[0], comparator: text[1], rhs: text[2]}
    }
    else if(span.hasClass('operator')){
        var operator = span.text()
        object[operator] = (object[operator] || [])
        var children = $(current_node).children('ul').children('li')
        for(var i = 0; i < children.length; i++){
            var child_pql = prepare_json([children[i]])
            object[operator].push(child_pql)
        }
    }
    return object
}

以下是调用该函数的代码:
var parent_node = $('#parent_of_all').children('li')
var json = JSON.stringify(prepare_pql_json(parent_node), null, 2)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接