English 中文(简体)
PHP: Convert <ul> <li> Tree HTML tag to an array
原标题:

I m using jsTree and I need to convert this HTML tag tree code <ul> <li> to a PHP array. The jsTree HTML tag will be passed to PHP to be parsed and store in a structured tree PHP array(see below for the PHP array structure).

Additional question: Is my desired PHP array structure good or you can suggest a good structure? I m open for suggestions.

Thanks in advance :)

Cheers, Mark

jsTree Screenshot:

alt text

HTML Tree String:

<ul class="ltr">
<li id="phtml_1" class="  open">
    <a style="" class=" " href="#"><ins>&nbsp;</ins>Folder 1</a>
    <ul>
    <li class="leaf" id="phtml_2">
        <a style="" class=" " href="#"><ins>&nbsp;</ins>Child 1.1</a>
    </li>
    <li class="open" id="phtml_3">
        <a style="" class=" " href="#"><ins>&nbsp;</ins>Folder 1.1</a>
        <ul>
        <li class="leaf last" rel="default">
            <a href="" style="" class=" "><ins>&nbsp;</ins>Child 1.1.1</a>
        </li>
        </ul>
    </li>
    <li class="last open" rel="default">
        <a href="" style="" class=" "><ins>&nbsp;</ins>Folder 1.2</a>
        <ul>
        <li class="leaf" rel="default">
            <a href="" style="" class=" "><ins>&nbsp;</ins>Child 1.2.1</a>
        </li>
        <li class="leaf last" rel="default">
            <a href="" style="" class=" "><ins>&nbsp;</ins>Child 1.2.2</a>
        </li>
        </ul>
    </li>
    </ul>
</li>
<li id="phtml_5" class="file open">
    <a style="" class=" " href="#"><ins>&nbsp;</ins>Folder 2</a>
    <ul>
    <li class="leaf" rel="default">
        <a href="" style="" class=" "><ins>&nbsp;</ins>Child 2.1</a>
    </li>
    <li class="leaf last" rel="default">
        <a href="" style="" class="clicked"><ins>&nbsp;</ins>Child 2.2</a>
    </li>
    </ul>
</li>
<li class="leaf last" rel="default">
    <a href="" style="" class=" "><ins>&nbsp;</ins>Outer Child</a>
</li>
</ul>

PHP Array Structure:

<?php
$tree_array = array(
     Folder 1  => array(
         Child 1.1 ,
         Folder 1.1  => array(
             Child 1.1.1 
        ),
         Folder 1.2  => array(
             Child 1.2.1 ,
             Child 1.2.2 
        ),
    ),
     Folder 2  => array(
         Child 2.1 ,
         Child 2.2 
    ),
     Outer Child 
);

echo  <pre> ,print_r($tree_array), </pre> ;
?>

PHP print_r Output:

Array
(
    [Folder 1] => Array
        (
            [0] => Child 1.1
            [Folder 1.1] => Array
                (
                    [0] => Child 1.1.1
                )

            [Folder 1.2] => Array
                (
                    [0] => Child 1.2.1
                    [1] => Child 1.2.2
                )

        )

    [Folder 2] => Array
        (
            [0] => Child 2.1
            [1] => Child 2.2
        )

    [0] => Outer Child
)
最佳回答

Regarding:

My problem I m having a hard time parsing the string HTML tag and save it in a PHP array.

I suggest that you use an HTML parser, such as simplehtmldom. This will allow you to traverse over HTML DOM just the way you want.

Here is a quick and dirty UL walking script:

<?php
    require_once( "simplehtmldom/simple_html_dom.php" );
    $DOM = file_get_html( "test.htm" );
    $ARR = array( );
    function WalkUL( $ul, &$ar )
    {
        foreach( $ul->children as $li )
        {
            if ( $li->tag != "li" )
            {
                continue;
            }
            $arar = array( );
            foreach( $li->children as $ulul )
            {
                if ( $ulul->tag != "ul" )
                {
                    continue;
                }
                WalkUL( $ulul, $arar );
            }
            $ar[ $li->find( "a", 0 )->plaintext ] = $arar;
        }
    }
    WalkUL( $DOM->find( "ul", 0 ), $ARR );
    print_r( $ARR );
?>

Its output, not exactly as you wanted it but close:

Array
(
    [Folder 1] => Array
        (
            [Child 1.1] => Array
                (
                )
            [Folder 1.1] => Array
                (
                    [Child 1.1.1] => Array
                        (
                        )
                )
            [Folder 1.2] => Array
                (
                    [Child 1.2.1] => Array
                        (
                        )
                    [Child 1.2.2] => Array
                        (
                        )
                )
        )
    [Folder 2] => Array
        (
            [Child 2.1] => Array
                (
                )
            [Child 2.2] => Array
                (
                )
        )
    [Outer Child] => Array
        (
        )
)
问题回答

Instead of messing with html you should submit the tree data in a more programmer-friendly format.

$( #saveButton ).click(function() {
    var treeData = $.tree.reference($( #sortableTree )).get(undefined,  json );
    var tmp = serializeTree(treeData, 0);
    // now json-encode tmp and submit it
});

function serializeTree(nodes, parent)
{
    var parents = {};
    var childOrder = []
    var childOrders = {};
    for(var i = 0; i < nodes.length; i++)
    {
        var node = nodes[i];
        var id = node.attributes.id.substr(5); // assuming the id looks like  abcd-ID 
        parents[id] = parent;
        childOrder.push(id);
        if(node.children)
        {
            var tmp = serializeTree(node.children, id);
            for(var id in tmp[0])
                parents[id] = tmp[0][id];
            for(var id in tmp[1])
                childOrders[id] = tmp[1][id]
        }
    }

    childOrders[parent] = childOrder;

    return [parents, childOrders];
}

Just for referecence: there s also a jQuery plugin for serializing a HTML DOM Tree of <ol> and <ul> lists: http://www.drakedata.com/serializetree/sampleTree.html - it converts a nested structure of <ol> and <ul> lists to a string which can be used as an associated php array.

If you have a UL that does not contain any href elements (e.g. just plain text nexted ul).. I ve adjusted Salman s simplehtmldom code to work with that:

$DOM = str_get_html( $catshtml );
$ARR = array( );
function WalkUL( $ul, &$ar )
{
    foreach( $ul->children as $li )
    {
        if ( $li->tag != "li" )
        {
            continue;
        }
        $arar = array( );
        foreach( $li->children as $ulul )
        {
            if ( $ulul->tag != "ul" )
            {
                continue;
            }
            WalkUL( $ulul, $arar );
        }
        $ar[ trim(preg_replace("#</?[a-z]+[^>]*>(.+</[a-z]+[^>]*>|)#is","",$li->innertext)) ] = $arar;
    }
}
WalkUL( $DOM->find( "ul", 0 ), $ARR );
echo "<pre>"; print_r( $ARR );




相关问题
Brute-force/DoS prevention in PHP [closed]

I am trying to write a script to prevent brute-force login attempts in a website I m building. The logic goes something like this: User sends login information. Check if username and password is ...

please can anyone check this while loop and if condition

<?php $con=mysql_connect("localhost","mts","mts"); if(!con) { die( unable to connect . mysql_error()); } mysql_select_db("mts",$con); /* date_default_timezone_set ("Asia/Calcutta"); $date = ...

定值美元

如何确认来自正确来源的数字。

Generating a drop down list of timezones with PHP

Most sites need some way to show the dates on the site in the users preferred timezone. Below are two lists that I found and then one method using the built in PHP DateTime class in PHP 5. I need ...

Text as watermarking in PHP

I want to create text as a watermark for an image. the water mark should have the following properties front: Impact color: white opacity: 31% Font style: regular, bold Bevel and Emboss size: 30 ...

How does php cast boolean variables?

How does php cast boolean variables? I was trying to save a boolean value to an array: $result["Users"]["is_login"] = true; but when I use debug the is_login value is blank. and when I do ...

热门标签