简体   繁体   English

PHP Jquery:将HTML转换为来自给定URL的JSON,并创建html元素的树视图

[英]PHP Jquery:Convert HTML to JSON from given url and create a tree view of html elements

Basically I have a textbox where I'll enter URL and click "OK button", It will show preview of HTML at left side of page; 基本上我有一个文本框,我将输入URL并单击“确定按钮”,它将在页面左侧显示HTML的预览; and right side will have a tree view of HTML tags (body, header, div, span, etc.) used in HTML as attached image. 并且右侧将具有HTML标记(正文,标题,div,span等)的树视图,在HTML中用作附加图像。 Expected JSON result should be as end of this question. 预期的JSON结果应该是这个问题的结尾。 I am failing traversing JSON and creating tree. 我无法遍历JSON并创建树。 I tried the following: 我尝试了以下方法:

HTML and JS code: HTML和JS代码:

<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ABC</title>
<link rel="stylesheet" type="text/css" href="css/main.css" />
</head>
<body>
<div id="wrapper">
    <header>
        <h1 class="logo"><img src="images/logo.png" alt="" title="" /></h1>
    </header>
    <div id="container">
        <div class="search-box">
            <input type="text" id="url" value="" class="txt-box" />
            <input type="button" value="OK" class="btn-search" />
        </div>
        <div class="inner-wrap">
            <div class="left-wrap" id="preview-sec">

            </div>
            <div class="right-wrap" id="tree-sec">

            </div>
        </div>
    </div>    
</div>

<script type="text/javascript" language="javascript" src="js/jquery-1.11.1.js"></script><!-- Jquery plugin -->
<script>
var counter = 0;
$(document).ready(function(){
    $('.btn-search').click(function(){
        if ($('#url').val() != '') {
            $.get(
                'http://localhost/test/getHTML.php', {url:$('#url').val()},
                function(response) {
                    $('#preview-sec').html(response);
            },'html');
            $.getJSON('http://localhost/test/results.json', function(json) {    
                traverse(json,0);               
            });
        }
    });
});
function traverse(obj,id){
    if (typeof(obj)=="object") {
        if (id == 0) {
            $('#tree-sec').append('<ul></ul>');
        } else {
            $(id).append('<ul></ul>');
        }
        $.each(obj, function(i,val){
            if (i != 'attributes' && i != 'value') {
                counter += 1;
                var li_populate = "<li id="+i+"-"+counter+">"+i+"</li>"; 
                if (id == 0) {
                    $('#tree-sec ul').append(li_populate);
                } else {
                    $(id).find('ul').append(li_populate);
                }
                traverse(val,"#"+i+"-"+counter);
            }
        })
    }
}
</script>
</body>
</html>

PHP code: PHP代码:

<?php
    $url = $_GET['url'];
    $html = file_get_contents($url);
    function html_to_obj($html) {
        $dom = new DOMDocument();
        $dom->loadHTML($html);
        return element_to_obj($dom->documentElement);
    }

    function element_to_obj($element) {
        //print_r($element);
        $obj = array();
        $attr = array();
        $arr = array();
        $name = $element->tagName;
        foreach ($element->attributes as $attribute) {
            $attr[$attribute->name] = $attribute->value;
            if ($attribute->name == 'id') {
                $name .= '#'.$attribute->value;
            }
        }
        if (!empty($attr)) {
            $arr["attributes"] = $attr;
        }
        if ($element->nodeValue != '') {
            $arr["value"] = $element->nodeValue;
        }

        foreach ($element->childNodes as $subElement) {         
            if ($subElement->nodeType == XML_TEXT_NODE) {

            }
            elseif ($subElement->nodeType == XML_CDATA_SECTION_NODE) {

            }
            else {
                $arr["child_nodes"][] = element_to_obj($subElement);
            }
        }
        $obj[$name] = $arr;
        return $obj;
    }
    $json = json_encode(html_to_obj($html));
    $fp = fopen('results.json', 'w');
    fwrite($fp,$json);
    fclose($fp);
    echo $html;exit();
?>

JSON tree output: JSON树输出:

在此输入图像描述

JSON Result: JSON结果:

    {
    "html": {
        "attributes": {
            "lang": "en"
        },
        "value": "Test Development Test\r\n            *{\r\n                box-sizing:border-box;\r\n            }\r\n            body {\r\n                margin:0;\r\n                font-family: sans-serif;\r\n                color: #999;\r\n            }\r\n            a, a:visited {\r\n                text-decoration:none;\r\n            }\r\n            .movie-list .movie{\r\n                width:250px;\r\n                float:left;\r\n                margin-right:25px;\r\n            }\r\n            .movie-list .movie img{\r\n                width:100%;\r\n            }\r\n            .movie-list .movie a.title{\r\n                text-decoration:none;\r\n                color:#999;\r\n                font-weight:bold;\r\n                font-size:18px;\r\n                line-height:25px;\r\n            }\r\n            .movie-list .movie .synopsis{\r\n                font-size:14px;\r\n                line-height:20px;\r\n            }\r\n",
        "child_nodes": {
            "head": {
                "child_nodes": {
                    "meta": {
                        "attributes": {
                            "name": "description",
                            "content": "A ast of animated movies"
                        }
                    },
                    "title": {
                        "value": "Test Development Test"
                    },
                    "style": {
                        "attributes": {
                            "type": "text/css"
                        },
                        "value": "\r\n            *{\r\n                box-sizing:border-box;\r\n            }\r\n            body {\r\n                margin:0;\r\n                font-family: sans-serif;\r\n                color: #999;\r\n            }\r\n            a, a:visited {\r\n                text-decoration:none;\r\n            }\r\n            .movie-list .movie{\r\n                width:250px;\r\n                float:left;\r\n                margin-right:25px;\r\n            }\r\n            .movie-list .movie img{\r\n                width:100%;\r\n            }\r\n            .movie-list .movie a.title{\r\n                text-decoration:none;\r\n                color:#999;\r\n                font-weight:bold;\r\n                font-size:18px;\r\n                line-height:25px;\r\n            }\r\n            .movie-list .movie .synopsis{\r\n                font-size:14px;\r\n                line-height:20px;\r\n            }\r\n"
                    }
                }
            },
            "body": {
                "child_nodes": {
                    "h1": {
                        "value": "List of animated movies"
                    },
                    "div": {
                        "attributes": {
                            "class": "movie-list"
                        },
                        "child_nodes": {
                            "div#bh_6": {
                                "attributes": {
                                    "class": "movie",
                                    "id": "bh_6",
                                    "data-year": "2014"
                                },
                                "child_nodes": {
                                    "img": {
                                        "attributes": {
                                            "src": "http://ia.media-imdb.com/images/M/MV5BMjI4MTIzODU2NV5BMl5BanBnXkFtZTgwMjE0NDAwMjE@._V1_SY317_CR0,0,214,317_AL_.jpg"
                                        }
                                    },
                                    "a": {
                                        "attributes": {
                                            "class": "title",
                                            "href": "http://www.imdb.com/title/tt2245084/"
                                        },
                                        "value": "Big Hero 6"
                                    },
                                    "div": {
                                        "attributes": {
                                            "class": "synopsis"
                                        },
                                        "value": "The special bond that develops between plus-sized inflatable robot Baymax, and prodigy Hiro Hamada, who team up with a group of friends to form a band of high-tech heroes."
                                    }
                                }
                            },
                            "div#tlm": {
                                "attributes": {
                                    "class": "movie",
                                    "id": "tlm",
                                    "data-year": "2014"
                                },
                                "child_nodes": {
                                    "img": {
                                        "attributes": {
                                            "src": "http://ia.media-imdb.com/images/M/MV5BMTg4MDk1ODExN15BMl5BanBnXkFtZTgwNzIyNjg3MDE@._V1_SX214_AL_.jpg"
                                        }
                                    },
                                    "a": {
                                        "attributes": {
                                            "class": "title",
                                            "href": "http://www.imdb.com/title/tt1490017/"
                                        },
                                        "value": "The Lego Movie"
                                    },
                                    "div": {
                                        "attributes": {
                                            "class": "synopsis"
                                        },
                                        "value": "An ordinary Lego construction worker, thought to be the prophesied 'Special', is recruited to join a quest to stop an evil tyrant from gluing the Lego universe into eternal stasis."
                                    }
                                }
                            },
                            "div#httyd": {
                                "attributes": {
                                    "class": "movie",
                                    "id": "httyd",
                                    "data-year": "2010"
                                },
                                "child_nodes": {
                                    "img": {
                                        "attributes": {
                                            "src": "http://ia.media-imdb.com/images/M/MV5BMjA5NDQyMjc2NF5BMl5BanBnXkFtZTcwMjg5ODcyMw@@._V1_SX214_AL_.jpg"
                                        }
                                    },
                                    "a": {
                                        "attributes": {
                                            "class": "title",
                                            "href": "http://www.imdb.com/title/tt0892769/"
                                        },
                                        "value": "How to Train Your Dragon"
                                    },
                                    "div": {
                                        "attributes": {
                                            "class": "synopsis"
                                        },
                                        "value": "A hapless young Viking who aspires to hunt dragons becomes the unlikely friend of a young dragon himself, and learns there may be more to the creatures than he assumed."
                                    }
                                }
                            },
                            "div#up": {
                                "attributes": {
                                    "class": "movie",
                                    "id": "up",
                                    "data-year": "2009"
                                },
                                "child_nodes": {
                                    "img": {
                                        "attributes": {
                                            "src": "http://ia.media-imdb.com/images/M/MV5BMTk3NDE2NzI4NF5BMl5BanBnXkFtZTgwNzE1MzEyMTE@._V1_SX214_AL_.jpg"
                                        }
                                    },
                                    "a": {
                                        "attributes": {
                                            "class": "title",
                                            "href": "http://www.imdb.com/title/tt1049413/"
                                        },
                                        "value": "Up"
                                    },
                                    "div": {
                                        "attributes": {
                                            "class": "synopsis"
                                        },
                                        "value": "By tying thousands of balloons to his home, 78-year-old Carl sets out to fulfill his lifelong dream to see the wilds of South America. Russell, a wilderness explorer 70 years younger, inadvertently becomes a stowaway."
                                    }
                                }
                            },
                            "div#mi": {
                                "attributes": {
                                    "class": "movie",
                                    "id": "mi",
                                    "data-year": "2001"
                                },
                                "child_nodes": {
                                    "img": {
                                        "attributes": {
                                            "src": "http://ia.media-imdb.com/images/M/MV5BMTY1NTI0ODUyOF5BMl5BanBnXkFtZTgwNTEyNjQ0MDE@._V1_SX214_AL_.jpg"
                                        }
                                    },
                                    "a": {
                                        "attributes": {
                                            "class": "title",
                                            "href": "http://www.imdb.com/title/tt0198781/"
                                        },
                                        "value": "Monsters, Inc."
                                    },
                                    "div": {
                                        "attributes": {
                                            "class": "synopsis"
                                        },
                                        "value": "Monsters generate their city's power by scaring children, but they are terribly afraid themselves of being contaminated by children, so when one enters Monstropolis, top scarer Sulley finds his world disrupted."
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

As per your question, the part where you traverse the returned json object and create the tree is problematic. 根据您的问题,您遍历返回的json对象并创建树的部分是有问题的。 In your code, the recursive function to traverse the json data had a few minor issues with the generate ul code. 在您的代码中,遍历json数据的递归函数对生成ul代码有一些小问题。 The structure of the return object made it a bit challenging. 返回对象的结构使其有点具有挑战性。

I was able to modify your html/javascript code a bit (without changing it too much) to print out the tree. 我能够修改你的html/javascript代码(不要太多改变)来打印出树。 The relevant code below: 相关代码如下:

CSS: CSS:

div#tree-sec ul ul{
    margin-left: 25px;
}
div#tree-sec ul li{
    color: #666;
}
div#tree-sec ul a{
    color: #111;
    text-decoration: underline;
    cursor: pointer;
}   
div#tree-sec ul a:hover {
    text-decoration: none;
}
div#tree-sec ul.collapsible{
    /* Custom parent styles here... */
    /* Such as a folder icon or 'plus' sign */
}

HTML & JS: HTML和JS:

...
...
<div class="inner-wrap">
    <div class="left-wrap" id="preview-sec">
        <iframe id="preview"></iframe>
    </div>
    <div class="right-wrap" id="tree-sec">
        <ul id="treehtml1"></ul>
    </div>
</div>
....
....
<script type="text/javascript">
    var counter = 0;
    $(document).ready(function(){
        $('.btn-search').click(function(){
            if ($('#url').val() != '') {
                $.get('http://localhost/test/getHTML.php', {url:$('#url').val()}, function(response) {
                    $('#preview-sec').html(response);
                },'html');
                $.getJSON('http://localhost/test/results.json', function(json) {    
                    if(typeof(json) == "object"){
                        traverse(json,'html',1);  
                        makeCollapsible();             
                    }
                });
             }
         });
     });

     function traverse(obj, element, counter){
         for (var i in obj){
             $("#tree"+element+counter).append("<li id='"+i+counter+"'>"+i+"</li>"); // Add element to the tree
             if(obj[i].hasOwnProperty('child_nodes')){
                 $("#"+i+counter).append("<ul id='tree"+i+(counter+1)+"'></ul>"); // If there are children, add a parent ul and pass the name to subsequent recursive calls for each child
                 for(var j in obj[i].child_nodes){
                     traverse(obj[i].child_nodes[j], i, counter + 1); // Recursive call to add child
                 }
             }
          }
      }

      function makeCollapsible(){
          $('ul.parent').each(function(i) {
              var parent_li = $(this).parent('li');
              parent_li.addClass('collapsible'); //Use this selector to style your parent items...

              // Temporarily remove the list from the
              // parent list item, wrap the remaining
              // text in an anchor, then reattach it.
              var sub_ul = $(this).remove();
              parent_li.wrapInner('<a/>').children('a').click(function() {
                 // Toggle the children...
                 sub_ul.toggle();
              });
              parent_li.append(sub_ul);
          });

          // Hide all lists except the outermost.
          $('ul ul').hide();
      }
</script>
....
....

This should provide a properly nested ul based tree. 这应该提供一个正确嵌套的基于ul的树。 If creating an image of the tree is a hard requirement, you're best bet is to properly style the generated ul code fragment, create an html page with it on the server and then use a server side tool such as wkhtmltoimage from the wkhtmltopdf package that can be used to render the html document into an image. 如果创建树的图像是一项艰难的要求,那么最好的办法是正确设置生成的ul代码片段的样式,在服务器上创建一个html页面,然后使用服务器端工具,例如wkhtmltopdf包中的wkhtmltoimage可用于将html文档呈现为图像。

Also, one other thing I would like to mention is that instead of loading the retrieved html into a div, I would recommend that you use an iframe as then, the retrieved html would not interfere with your current page. 另外,我想提到的另一件事是,不是将检索到的html加载到div中,我建议你使用iframe ,检索到的html不会干扰你当前的页面。 In my example above, I have added an iframe in the preview div . 在上面的示例中,我在预览div添加了一个iframe In such a case, you can use php to only output the json data and setting the iframe to preview the url would be as simple as assigning the url as the src attribute of the iframe . 在这种情况下,您可以使用php仅输出json数据并设置iframe以预览url就像将url指定为iframesrc属性一样简单。 Like this: $("#preview").prop("src", $("#url").val()) . 像这样: $("#preview").prop("src", $("#url").val())

Edit : Updated code with a fix. 编辑 :更新了修复代码。 Also added a new js function makeCollapsible() to retro-actively convert the ul into a clickable, collapsible tree structure as per OP's comment. 还添加了一个新的js函数makeCollapsible() ,根据OP的注释,将ul转换为可点击的可折叠树结构。 Also added relevant CSS styles to style the tree structure. 还添加了相关的CSS样式来设置树结构的样式。 The tree now looks like the below picture for me: 现在,树对我来说如下图所示:

可折叠,可点击的HTML树!

Addendum: This is a long answer, but it addresses specific problems and solutions for the code snippets you provided. 附录:这是一个很长的答案,但它解决了您提供的代码段的特定问题和解决方案。 I hope you and others will find it worth the time to compare. 我希望你和其他人都觉得值得花时间去比较。 :) :)


First, modify your PHP to make cleaner JSON 首先,修改你的PHP以制作更干净的JSON

When parsing the DOM, I recommend setting the element names from the returned object as the associative keys in $arr['child_nodes'] using array_merge() instead of pushing them onto the array as indexed items. 在解析DOM时,我建议使用array_merge()将返回对象中的元素名称设置为$arr['child_nodes']的关联键,而不是将它们作为索引项目推送到数组中。 To do this, $arr['child_nodes'] must be defined as an array first. 为此,必须首先将$arr['child_nodes']定义为数组。 Later, if no items get merged into it, you simply unset it before $arr gets added to the main object. 之后,如果没有项目合并到其中,您只需在$arr添加到主对象之前unset

This makes the final JSON result simpler to parse by precluding the need to use a nested loop in your javascript when building the tree. 这使得最终的JSON结果更容易解析,因为在构建树时不需要在javascript中使用嵌套循环。

I also recommend inserting conditional checks for ->length before doing foreach loops. 我还建议在执行foreach循环之前插入->length条件检查。 Your existing code was throwing "Warning" messages when zero-length elements entered into the loop. 当零长度元素进入循环时,您现有的代码会抛出“警告”消息。

Lastly, you may choose to simplify your logic for handling node types by replacing your current if, else if, else statement with a single if checking for $subElement->nodeType === XML_ELEMENT_NODE , which I think is what you're trying to accomplish. 最后,您可以选择简化处理节点类型的逻辑,方法是将当前if, else if, else语句替换为单个, if检查$subElement->nodeType === XML_ELEMENT_NODE ,我认为这是您要尝试的完成。

<?php
    $url  = $_GET['url'];
    $html = file_get_contents($url);
    function html_to_obj($html) {
        $dom = new DOMDocument();
        $dom->loadHTML($html);
        return element_to_obj($dom->documentElement);
    }
    function element_to_obj($element) {
        $obj = $attr = $arr = array();
        $name = $element->tagName;
        if ($element->attributes->length) {
            foreach ($element->attributes as $attribute) {
                $attr[$attribute->name] = $attribute->value;
                if ($attribute->name == 'id') {
                    $name .= '#'.$attribute->value;
                }
            }
        }
        if (!empty($attr)) {
            $arr["attributes"] = $attr;
        }
        if ($element->nodeValue != '') {
            $arr["value"] = $element->nodeValue;
        }
        if ($element->childNodes->length) {
            $arr["child_nodes"] = array();
            foreach ($element->childNodes as $subElement) {         
                if ($subElement->nodeType === XML_ELEMENT_NODE) {
                    $arr["child_nodes"] = array_merge($arr["child_nodes"], element_to_obj($subElement));
                }
            }
            if (!count($arr["child_nodes"])) {
                unset($arr["child_nodes"]);
            }
        }
        $obj[$name] = $arr;
        return $obj;
    }
    $json = json_encode(html_to_obj($html));
    $fp   = fopen('results.json', 'w');
    fwrite($fp, $json);
    fclose($fp);
?>

Use an iframe 使用iframe

Insert an empty iframe into which you will load your target site. 插入一个空的iframe,您将加载目标网站。 Inserting the markup from another site into yours can (and will likely) cause conflicts with your own code. 将标记从另一个站点插入到您的站点中可能(并且可能)会导致与您自己的代码冲突。

<div class="inner-wrap">
    <div class="left-wrap" id="preview-sec">
        <iframe src=""></iframe>
    </div>
    <div class="right-wrap" id="tree-sec">
    </div>
</div>

Simplify the traverse function, reorder async calls 简化遍历功能,重新排序异步调用

The traverse function was suffering from three flaws: traverse功能有三个缺陷:

  1. The use of a counter to create ids on the fly and then use jQuery to find previously made elements with those ids on which to append list items was a performance drain and confusing to debug. 使用计数器动态创建id,然后使用jQuery查找以前制作的元素以及那些附加列表项的ID,这是一个性能消耗和调试混乱。

  2. The use of .find() resulted in jQuery redundantly entering the recursive call and appending multi-redundant child nodes to the tree. 使用.find()导致jQuery冗余地进入递归调用并将多冗余子节点附加到树。

  3. Because it is the callback of a separate asynchronous call, it could execute before the first asynchronous call to getHTML.php had finished. 因为它是一个单独的异步调用的回调,所以它可以在对getHTML.php的第一次异步调用完成之前执行。

Move the async call to get the JSON into the callback function on the first async call to prevent it from fetching incomplete or old JSON from the server. 移动异步调用以在第一次异步调用中将JSON引入回调函数,以防止它从服务器获取不完整或旧的JSON。

You should also use this first callback to set the iframe src and empty the #tree-sec container, so that subsequent actions don't append more than one tree. 您还应该使用此第一个回调来设置iframe src并清空#tree-sec容器,以便后续操作不会追加多个树。 You could accomplish the same thing by using .replace() instead of .empty() followed by .append() . 您可以使用.replace()而不是.empty()后跟.append()来完成同样的事情。

To build the tree, I recommend the following simpler approach, which recursively builds the list as a string so that the .append method is only called once. 为了构建树,我建议使用以下更简单的方法,它以字符串的形式递归地构建列表,以便只调用一次.append方法。 For larger trees, this will dramatically improve performance. 对于较大的树木,这将显着提高性能。

You may introduce a counter and dynamically assigned ids to this function if you want to, but I left it out to demonstrate more clearly that they are not needed to build the tree. 如果你愿意,你可以为这个函数引入一个计数器和动态分配的id,但我把它留下来更清楚地证明它们不需要构建树。

I also recommend checking for the existence of child nodes before entering a recursive call. 我还建议在进入递归调用之前检查子节点是否存在。 Doing this check allows you to pass in only the child nodes object, which – because of the new JSON resulting from changes made to the PHP script – now contains tag names as the keys instead of indexed keys with the elements as children. 执行此检查允许您仅传入子节点对象,因为由于对PHP脚本所做的更改而产生的新JSON,现在包含标记名称作为键而不是带有元素作为子项的索引键。 If we hadn't simplified the JSON, a second loop would have been required at this point to retrieve each element. 如果我们没有简化JSON,那么此时需要第二个循环来检索每个元素。

You'll also notice the inclusion of aria- attributes and role attributes. 您还会注意到包含aria-属性和role属性。 This sets you up to be fully accessible if you choose. 如果您愿意,这将使您完全可以访问。

See: Using the WAI-ARIA aria-expanded state to mark expandable and collapsible regions (w3.org) 请参阅: 使用WAI-ARIA咏叹调扩展状态标记可扩展和可折叠区域(w3.org)

It also provides you with a convenient and semantic way to control CSS and toggle state, which you can see demonstrated in the additional click handler added at the bottom of the script and the CSS example at the bottom of this answer. 它还为您提供了一种方便和语义的方式来控制CSS和切换状态,您可以在脚本底部添加的附加单击处理程序和此答案底部的CSS示例中看到这一点。

$(document).ready(function () {
    function traverse(data, firstTime) {
        if (typeof data === 'object') {  
            var ul = '<ul role="' + (firstTime ? 'tree' : 'group' ) + '">';
            $.each(data, function (key, val) {
                if (key !== 'attributes' && key !== 'value') {
                    if (val['child_nodes']) {
                        ul += '<li aria-expanded="true" role="tree-item" tabindex="0">';
                        ul += key;
                        ul += traverse(val['child_nodes']);
                        ul += '</li>';
                    } else {
                        ul += '<li role="tree-item" tabindex="0">';
                        ul += key;
                        ul += '</li>';
                    }
                }
            });
            ul += '</ul>';
            return ul;
        }
    }
    $('.btn-search').on('click', function () {
        var url = $('#url').val();
        if (url) {
            $.get(
                'getHTML.php',
                {
                    url: url
                },
                function () {
                    $('#preview-sec iframe').attr('src', url);
                    $('#tree-sec').empty();
                    $.get(
                        'results.json',
                        function (json) {
                            $('#tree-sec').append(traverse(json, true));
                        },
                        'json'
                    );
                },
                'html'
            );
        }
    });
    $('#tree-sec').on('click', 'li[aria-expanded]', function (e) {
        e.stopPropagation();
        $(this)
            .attr('aria-expanded', function (i, attr) {
                return !(attr === 'true');
            })
            .children('ul')
            .attr('aria-hidden', function (i, attr) {
                return !(attr === 'true');
            })
            .toggle();
    });
});

Bonus: Use attribute selectors in the CSS 奖励:在CSS中使用属性选择器

Finally, as mentioned above, the existence of the aria- and role attributes provides a semantic and convenient way to control the styles. 最后,如上所述, aria-role属性的存在提供了一种语义和方便的方式来控制样式。

ul[role='tree'] {
    margin-left: 1em;
    padding-left: 0;
}
ul[role='tree'] li {
    cursor: default;
    margin: 0;
    padding: 0 0 0 20px;
    font: normal 1em sans-serif;
    color: #333;
}
ul[role='tree'] li[aria-expanded] {
    cursor: pointer;
    font-weight: bold;
    color: #111;
    background: transparent 0 0 no-repeat url('images/arrow-sprite.png');
}
ul[role='tree'] li[aria-expanded="true"] {
    background-position: 0 0;
}
ul[role='tree'] li[aria-expanded="false"] {
    background-position: 0 20px;
}

Check out this Library which is wrote by Jack. 看看这个由杰克写的图书馆

https://github.com/Jxck/html2json https://github.com/Jxck/html2json

Hope it helps you. 希望它能帮到你。

Look at XSLT processing. 看看XSLT处理。 works fine with much less code effort 使用更少的代码工作可以正常工作

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="json.xml"?>
<html>
<body>
    <h1>title</h1>
    <h2>title 2</h2>
    <h3>title 3</h3>
    <ul>
        <li>t1</li>
        <li>t2</li>
        <li>t3</li>
    </ul>
</body>
</html>

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template name="json" match="/">
<xsl:for-each select="*">
{"<xsl:value-of select="local-name()"/>": "<xsl:if test="count(*)=0"><xsl:value-of select="text()"/></xsl:if>",
"attributes": {<xsl:for-each select="@*"><xsl:if test="position()>1">,</xsl:if>"<xsl:value-of select="local-name()"/>": "<xsl:value-of select="text()"/>"</xsl:for-each>},<xsl:call-template name="json"/>}</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

为HTML标记构造多维PHP数组,然后将该数组作为php内置函数json_encode($ array)的输入,并返回树形结构的json输出

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM