Jquery树遍历 - 嵌套的无序列表元素到JSON

时间:2010-07-03 20:22:12

标签: jquery json tree list traversal

好的,现在我在这里有一个无序列表:

<ul id="mycustomid">
    <li><a href="url of Item A" title="sometitle">Item A</a>
        <ul class="children">
           <li><a href="url of Child1 of A" title="sometitle">Child1 of A</a>
               <ul class="children">
                 <li><a href="url of Grandchild of A" title="sometitle">Grandchild of A</a>
                    <ul class="children">
                       <li><a href="url of Grand Grand child of A" title="sometitle">Grand Grand child of A</a></li>
                    </ul>
                </li>
               </ul>
           </li>
        </ul>
    </li>
    <li><a href="url of Item B" title="sometitle">Item B</a></li>
    <li><a href="url of Item C" title="sometitle">Item C</a></li>
</ul>

基本上,我想将此数据转换为JSON实体。我想在 Jquery 中完成这项工作,我想我真的很难做到这一点。上面的列表只是一个例子,实际上,我的列表理想情况下会有更多的孩子,并且可能是'n'级别深(意思是,它将有孙子孙子孙子孙子孙女......或者更多)我失去了无数在这个小时睡觉,我不认为我会去任何地方:(

我想提取这些东西:锚点内的文本,锚点的url和锚点的标题,并将它们放到JSON实体上

上面列表的JSON格式如下:

{
        name: "Item A",
        url: "url of Item A",
        title: "sometitle",
        children: [{
                   name: "Child1 of A",
                   url: "url of Child1 of A",
                   title: "sometitle",
                   children: [{
                                name: "Grandchild of A",
                                url: "url of Grandchild of A",
                                title: "sometitle",
                                children: [{
                                           name: "Grand Grand child of A",
                                           url: "url of Grand Grand child of A",
                                           title: "sometitle",
                                           children: []
                                           }]
                              }]
                   }]
},
           {
            name: "Item B",
            url: "url of Item B",
            title: "sometitle",
            children: []
           },
           {
            name: "Item C",
            url: "url of Item C",
            title: "sometitle",
            children: []
           }

一些有用的参考资料:

Javascript解决方案: Traversing unordered lists using Javascript/Jquery

^这个可能有效,但我需要的JSON输出格式如上所示,而不是这个脚本输出的内容:(

其他参考资料:

How do I put unordered list items into an array

http://jsfiddle.net/yS6ZJ/1/

http://jsfiddle.net/CLLts/

http://jsfiddle.net/cWnwt/

有人请帮忙:(
在许多不眠之夜的时候,我的脑子一直在挣扎......(P.s - 我花了大约40多分钟就把整个页面和代码一起写了)

谢谢。

3 个答案:

答案 0 :(得分:9)

啊,这是一个有趣的小递归练习。我有一个时刻,这就是我将如何做到这一点。这在递归上可以很深层次地运行,但假设您的数据不够深,无法分解内存(如果浏览器太深,则会在浏览器中出现递归中断)。至少10级以上应该没问题。

我对此进行了测试,看起来有效,只需将其保存在HTML文件中即可。您应该没问题。

很抱歉没有太多评论(从技术上讲,根本没有评论:),这假设您阅读jQuery和JS代码很好。如果您有疑问,请在评论中提问,我很乐意解释。

<!DOCTYPE HTML>
<html>
<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <title>Recursive list processor example</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
    <script type="text/javascript">

$(document).ready(function() {

    var out = [];

    function processOneLi(node) {       

        var aNode = node.children("a:first");
        var retVal = {
            "title": aNode.attr("title"),
            "url": aNode.attr("href"),
            "name": aNode.text()
        };

        node.find("> .children > li").each(function() {
            if (!retVal.hasOwnProperty("children")) {
                retVal.children = [];
            }
            retVal.children.push(processOneLi($(this)));
        });

        return retVal;
    }

    $("#mycustomid").children("li").each(function() {
        out.push(processOneLi($(this)));
    });


    console.log("got the following JSON from your HTML:", JSON.stringify(out));

});

    </script>
</head>
<body>
<ul id="mycustomid">
    <li><a href="http://example.com/urlOfItemA" title="sometitle">Item A</a>
        <ul class="children">
           <li><a href="http://example.com/urlOfItemAChild1" title="sometitle">Child1 of A</a>
               <ul class="children">
                 <li><a href="http://example.com/urlOfItemAGrandchild" title="sometitle">Grandchild of A</a>
                    <ul class="children">
                       <li><a href="http://example.com/urlOfItemAGrandGrandChild" title="sometitle">Grand Grand child of A</a></li>
                    </ul>
                </li>
               </ul>
           </li>
        </ul>
    </li>
    <li><a href="http://example.com/urlOfItemB" title="sometitle2">Item '"" B</a></li>
    <li><a href="http://example.com/urlOfItemC" title="sometitle3">Item C</a></li>
</ul>
</body>
</html>

答案 1 :(得分:2)

看起来像一个递归解决方案,使用一个函数用于列表元素(子元素)的集合,一个用于列表元素。注意我假设您希望将其格式化为字符串,并且它实际上表示为数组。

$(function() {
    var json = formatListElements( $('#mycustomid > li') );
});

function formatListElements( elems )
{
    var contents = [] 
    $.each( elems, function( index, elem ) {
        contents[index] = formatListElement( elem );
    }
    return '[' + contents.join(', ') + ']';
}

function formatListElement( elem )
{
   var anchor = $(elem).children('a:first');
   return '{ "name": "' + quote( anchor.text() )
                + '", "url": "' + quote( anchor.attr('href') )
                + '", "title": "' + quote( anchor.attr('title') )
                + '", "children": ' + formatListElements( $(elem).find('> ul > li')
        + '}';
}

function quote( str )
{
    return str.replace( /"/g, '\\\"' );
}

答案 2 :(得分:2)

以下源代码是我的解决方案。我认为它足够明确地向隐藏ul到json对象显示原则。祝你好运:)

&#13;
&#13;
$(function() {

  function buildJSON($li) {
    var subObj = { "name": $li.contents().eq(0).text().trim() };
    $li.children('ul').children().each(function() {
      if (!subObj.children) { subObj.children = []; }
      subObj.children.push(buildJSON($(this)));
    });
    return subObj;
  }
    
  var obj = buildJSON($("#ul-data").children());
  $('body').append('<pre>').find('pre').append(JSON.stringify(obj, null, 2));

});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="ul-data">
  <li><a href="#">AAA</a>
    <ul>
      <li><a href="#">DDD</a>
        <ul>
          <li><a href="#">EEE</a>
            <ul>
              <li><a href="#">FFF</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li><a href="#">BBB</a></li>
      <li><a href="#">CCC</a></li>
    </ul>
  </li>
</ul>
&#13;
&#13;
&#13;