[英]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 "• " . $node2->textContent . "<br>";
} else {
if ($node2->lastChild->childNodes) {
foreach ($node2->lastChild->childNodes as $node3) {
if ($node3->nodeName == 'li'
&&
$node3->lastChild->nodeName != 'ul'
) {
echo "• • " . $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.