簡體   English   中英

轉換嵌套<ul><li>到 PHP 嵌套數組

[英]Convert nested <ul><li> to PHP nested array

我想將嵌套的ul li轉換為 PHP 數組。

我擁有的 HTML 代碼如下所示:

<ul id="main-menu">
    <li id="firstNavItem"><a href="index.html">Home</li>
    <li><a href="Warp.html">Warp</a>
        <ul>
            <li><a href="Warp-how-it-works.html">How it works</a>
            </li>
            <li><a href="Warp-Engine.html">Warp Engine</a>
            </li>
            <li><a href="WarpFactors.html">Warp Factors</a>
            </li>
            <li><a href="">Fuel</a>
                <ul>
                    <li><a href="Anti-Matter.html">Anti-Matter</a>
                    </li>
                    <li><a href="Deuterium.html">Deuterium</a>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
    <li><a href="Fact-or-Fiction.html">Fact or Fiction</li>
    <li><a href="StarTrek.html">Star Trek</a>
        <ul>
            <li><a href="Enterprise.html">Enterprise</a>
            </li>
            <li><a href="Voyager.html">Voyager</a>
            </li>
        </ul>
    </li>
    <li><a href="about.html">About</a>
    </li> </ul>

它必須轉換為數組。

我嘗試了幾種解析方法,但都失敗了。

我使用的方法之一是:

$doc = new \DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->loadHTML($data);
$i = 0;

while( is_object($finance = $doc->getElementsByTagName("li")->item($i)) )
{
    foreach($finance->childNodes as $nodename)
    {
        if($nodename->nodeName == 'li')
        {
            foreach($nodename->childNodes as $subNodes)
            {
                $arr[$i] = $subNodes->nodeValue.PHP_EOL;
            }
        }
        else
        {
            $s = explode('             ', $nodename->nodeValue);
            if (count($s) == 1)
            {
                $arr[$i] =$nodename->nodeValue;
            }
            else
            {
                $arr[$i] =  $s;
            }

        }
    }

    $i++;
}

下面的代碼給出了一個嵌套數組。 我認為輸出的數組應該是什么樣子還不清楚,但是這段代碼給出了以下內容:

Array
(
    [0] => Array
        (
            [key] => Home
            [items] => Array
                (
                )

        )

    [1] => Array
        (
            [key] => Warp
            [items] => Array
                (
                    [0] => Array
                        (
                            [key] => How it works
                            [items] => Array
                                (
                                )

                        )

                    [1] => Array
                        (
                            [key] => Warp Engine
                            [items] => Array
                                (
                                )

                        )

                    [2] => Array
                        (
                            [key] => Warp Factors
                            [items] => Array
                                (
                                )

                        )

                    [3] => Array
                        (
                            [key] => Fuel
                            [items] => Array
                                (
                                    [0] => Array
                                        (
                                            [key] => Anti-Matter
                                            [items] => Array
                                                (
                                                )

                                        )

                                    [1] => Array
                                        (
                                            [key] => Deuterium
                                            [items] => Array
                                                (
                                                )

                                        )

                                )

                        )

                )

        )

    [2] => Array
        (
            [key] => Fact or Fiction
            [items] => Array
                (
                )

        )

    [3] => Array
        (
            [key] => Star Trek
            [items] => Array
                (
                    [0] => Array
                        (
                            [key] => Enterprise
                            [items] => Array
                                (
                                )

                        )

                    [1] => Array
                        (
                            [key] => Voyager
                            [items] => Array
                                (
                                )

                        )

                )

        )

    [4] => Array
        (
            [key] => About
            [items] => Array
                (
                )

        )

)

代碼:

<?php

class Parser {

    private $elements = [];

    public function parse() {
        $doc = new \DOMDocument();
        $doc->preserveWhiteSpace = false;
        $doc->loadHTMLFile("./html.html");

        $this->parseChildNodes($doc, $this->elements);
    }

    private function parseChildNodes($node, & $arrayToPush) {
        $indexPushed = count($arrayToPush);

        if ($node->nodeName == "li") {
            $representation = [
                "key" => $this->getDisplayValueFromNode($node),
                "items" => []
            ];
            array_push($arrayToPush, $representation);
            $arrayToPush = & $arrayToPush[$indexPushed]["items"];
        }

        if ($node->childNodes == null) {
            return;
        }
        foreach ($node->childNodes as $child) {
            $this->parseChildNodes($child, $arrayToPush);
        }
    }

    /**
     * Get the value of the node's first element
     * In our case this is the text value of the anchor tag
     *
     * @param $node
     * @return String
     */
    private function getDisplayValueFromNode($node) {
        return $node->firstChild->nodeValue;
    }

    public function getElements() {
        return $this->elements;
    }
}

$parser = new Parser();
$parser->parse();
print_r($parser->getElements());

這並不容易,但我不知道您可以使用 PHP 訪問 DOM,因此這是一個有趣的挑戰。

這將適用於最多兩個深度的嵌套列表,您可以重構它以使其更容易處理更深的列表。

下面的代碼應該可以幫助您將列表放入數組中。 為了便於演示,我留下了 echo 語句。

<?php
    $data = <<<EOT
<ul id="main-menu">
    <li id="firstNavItem"><a href="index.html">Home</li>
    <li><a href="Warp.html">Warp</a>
        <ul>
            <li><a href="Warp-how-it-works.html">How it works</a>
            </li>
            <li><a href="Warp-Engine.html">Warp Engine</a>
            </li>
            <li><a href="WarpFactors.html">Warp Factors</a>
            </li>
            <li><a href="">Fuel</a>
                <ul>
                    <li><a href="Anti-Matter.html">Anti-Matter</a>
                    </li>
                    <li><a href="Deuterium.html">Deuterium</a>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
    <li><a href="Fact-or-Fiction.html">Fact or Fiction</li>
    <li><a href="StarTrek.html">Star Trek</a>
        <ul>
            <li><a href="Enterprise.html">Enterprise</a>
            </li>
            <li><a href="Voyager.html">Voyager</a>
            </li>
        </ul>
    </li>
    <li><a href="about.html">About</a>
    </li>
</ul>
EOT;

    $doc = new \DOMDocument();
    $doc->preserveWhiteSpace = false;
    $doc->loadHTML($data);

    $list = $doc->getElementsByTagName('ul')->item(0);
    foreach ($list->childNodes as $node) {
        if ($node->nodeName == 'li'
            &&
            $node->lastChild->nodeName != 'ul'
        ) {
            echo $node->textContent . "<br>";
        } else {
            if ($node->lastChild->childNodes) {
                foreach ($node->lastChild->childNodes as $node2) {
                    if ($node2->nodeName == 'li'
                        &&
                        $node2->lastChild->nodeName != 'ul'
                    ) {
                        echo "&bull; " . $node2->textContent . "<br>";
                    } else {
                        if ($node2->lastChild->childNodes) {
                            foreach ($node2->lastChild->childNodes as $node3) {
                                if ($node3->nodeName == 'li'
                                    &&
                                    $node3->lastChild->nodeName != 'ul'
                                ) {
                                    echo "&bull; &bull; " . $node3->textContent . "<br>";
                                }
                            }
                        }
                    }
                }
            }
        }
    }

getElementsByTagName()返回具有該名稱的所有節點(包括嵌套節點),因此無需額外搜索子節點。 下面片段中的代碼返回這個數組:

Array
(
    [0] => Home
    [1] => Warp
    [2] => How it works
    [3] => Warp Engine
    [4] => Warp Factors
    [5] => Fuel
    [6] => Anti-Matter
    [7] => Deuterium
    [8] => Fact or Fiction
    [9] => Star Trek
    [10] => Enterprise
    [11] => Voyager
    [12] => About
)

代碼:

<?php

class Parser {

    private $elements = [];

    public function parse() {
        $doc = new \DOMDocument();
        $doc->preserveWhiteSpace = false;
        $doc->loadHTMLFile("./html.html");

        foreach($doc->getElementsByTagName("li") as $node) {
            array_push($this->elements, $node->firstChild->nodeValue);
        }
    }

    /**
     * Get the value of the node's first element
     * In our case this is the text value of the anchor tag
     *
     * @param $node
     * @return String
     */
    private function getDisplayValueFromNode($node) {
        return $node->firstChild->nodeValue;
    }

    public function getElements() {
        return $this->elements;
    }
}

$parser = new Parser();
$parser->parse();
print_r($parser->getElements());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM