用平面数据在PHP中构建分层html标签 [英] Build hierarchical html tags in PHP from flat data

查看:157
本文介绍了用平面数据在PHP中构建分层html标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你如何用PHP中的数据构建一个层次化的标记集?

例如,嵌套列表:

 < div> 
< ul>
< li> foo
< / li>
< li> bar
< ul>
< li>子栏
< / li>
< / ul>
< / li>
< / ul>
< / div>

这可以通过像这样的平面数据来构建:

  nested_array = array(); 
nested_array [0] = array('name'=>'foo','depth'=> 0)
nested_array [1] = array('name'=>'bar', 'depth'=> 0)
nested_array [2] = array('name'=>'sub-bar','depth'=> 1)



如果它的格式与示例相似,那将会很不错。

解决方法

编辑:添加格式



正如评论中所述,您的数据结构有点奇怪。而不是使用文本操作(比如OIS),我更喜欢DOM:

 <?php 

$ nested_array = array();
$ nested_array [] = array('name'=>'foo','depth'=> 0);
$ nested_array [] = array('name'=>'bar','depth'=> 0);
$ nested_array [] = array('name'=>'sub-bar','depth'=> 1);
$ nested_array [] = array('name'=>'sub-sub-bar','depth'=> 2);
$ nested_array [] = array('name'=>'sub-bar2','depth'=> 1);
$ nested_array [] = array('name'=>'sub-sub-bar3','depth'=> 3);
$ nested_array [] = array('name'=>'sub-sub3','depth'=> 2);
$ nested_array [] = array('name'=>'baz','depth'=> 0);

$ doc = new DOMDocument('1.0','iso-8859-1');
$ doc-> formatOutput = true;
$ rootNode = $ doc-> createElement('div');
$ doc-> appendChild($ rootNode);

$ rootList = $ doc-> createElement('ul');
$ rootNode-> appendChild($ rootList);

$ listStack = array($ rootList); //创建的XML列表元素的堆栈
$ depth = 0; //当前深度

foreach($ nested_array as $ nael){
while($ depth <$ nael ['depth']){
//新列​​表元素
if($ listStack [$ depth] - > lastChild == null){
//一次超过一个等级
$ li = $ doc-> createElement('li') ;
$ listStack [$ depth] - > appendChild($ li);
}
$ listEl = $ doc-> createElement('ul');
$ listStack [$ depth] - > lastChild-> appendChild($ listEl);
array_push($ listStack,$ listEl);

$ depth ++;
}

while($ depth> $ nael ['depth']){
array_pop($ listStack);
$ depth--;
}

//添加元素本身
$ li = $ doc-> createElement('li');
$ li-> appendChild($ doc-> createTextNode($ nael ['name']));
$ listStack [$ depth] - > appendChild($ li);
}

echo $ doc-> saveXML();

您的格式约定有点奇怪。将最后一行替换为以下内容以实现它:

  printEl($ rootNode); 

function printEl(DOMElement $ el,$ depth = 0){
$ leftFiller = str_repeat(\ t,$ depth);
$ name = preg_replace('/ [^ a-zA-Z] /','',$ el-> tagName);

if($ el-> childNodes->长度== 0){
//空节点
echo $ leftFiller。 '<'。 $名称。 /> \\\
;
} else {
echo $ leftFiller。 '<'。 $名称。 > 中;
$ printedNL = false; ($ i = 0; $ i< $ el-> childNodes->长度; $ i ++){
$ c = $ el-> childNodes->的

。项目($ I);

if($ c instanceof DOMText){
echo htmlspecialchars($ c-> wholeText);
} elseif($ c instanceof DOMElement){
if(!$ printedNL){
$ printedNL = true;
回声\\\
;
}
printEl($ c,$ depth + 1);



if(!$ printedNL){
$ printedNL = true;
回声\\\
;
}

echo $ leftFiller。 '< /'。 $名称。 > \\\
;
}

}


How do you build a hierarchical set of tags with data in PHP?

For example, a nested list:

<div>
    <ul>
        <li>foo
        </li>
        <li>bar
            <ul>
                <li>sub-bar
                </li>
            </ul>
        </li>
    </ul>
</div>

This would be build from flat data like this:

nested_array = array();
nested_array[0] = array('name' => 'foo', 'depth' => 0)
nested_array[1] = array('name' => 'bar', 'depth' => 0)
nested_array[2] = array('name' => 'sub-bar', 'depth' => 1)

It would be nice if it were nicely formatted like the example, too.

解决方案

Edit: Added formatting

As already said in the comments, your data structure is somewhat strange. Instead of using text manipulation (like OIS), I prefer DOM:

<?php

$nested_array = array();
$nested_array[] = array('name' => 'foo', 'depth' => 0);
$nested_array[] = array('name' => 'bar', 'depth' => 0);
$nested_array[] = array('name' => 'sub-bar', 'depth' => 1);
$nested_array[] = array('name' => 'sub-sub-bar', 'depth' => 2);
$nested_array[] = array('name' => 'sub-bar2', 'depth' => 1);
$nested_array[] = array('name' => 'sub-sub-bar3', 'depth' => 3);
$nested_array[] = array('name' => 'sub-sub3', 'depth' => 2);
$nested_array[] = array('name' => 'baz', 'depth' => 0);

$doc = new DOMDocument('1.0', 'iso-8859-1');
$doc->formatOutput = true;
$rootNode = $doc->createElement('div');
$doc->appendChild($rootNode);

$rootList = $doc->createElement('ul');
$rootNode->appendChild($rootList);

$listStack = array($rootList); // Stack of created XML list elements
$depth = 0; // Current depth

foreach ($nested_array as $nael) {
    while ($depth < $nael['depth']) {
        // New list element
        if ($listStack[$depth]->lastChild == null) {
            // More than one level at once
            $li = $doc->createElement('li');
            $listStack[$depth]->appendChild($li);
        }
        $listEl = $doc->createElement('ul');
        $listStack[$depth]->lastChild->appendChild($listEl);
        array_push($listStack, $listEl);

        $depth++;
    }

    while ($depth > $nael['depth']) {
        array_pop($listStack);
        $depth--;
    }

    // Add the element itself
    $li = $doc->createElement('li');
    $li->appendChild($doc->createTextNode($nael['name']));
    $listStack[$depth]->appendChild($li);
}

echo $doc->saveXML();

Your formatting convention is kind of strange. Replace the last line with the following to achieve it:

printEl($rootNode);

function printEl(DOMElement $el, $depth = 0) {
    $leftFiller = str_repeat("\t", $depth);
    $name = preg_replace('/[^a-zA-Z]/', '', $el->tagName);

    if ($el->childNodes->length == 0) {
        // Empty node
        echo $leftFiller . '<' . $name . "/>\n";
    } else {
        echo $leftFiller . '<' . $name . ">";
        $printedNL = false;

        for ($i = 0;$i < $el->childNodes->length;$i++) {
            $c = $el->childNodes->item($i);

            if ($c instanceof DOMText) {
                echo htmlspecialchars($c->wholeText);
            } elseif ($c instanceof DOMElement) {
                if (!$printedNL) {
                    $printedNL = true;
                    echo "\n";
                }
                printEl($c, $depth+1);
            }
        }

        if (!$printedNL) {
            $printedNL = true;
            echo "\n";
        }

        echo $leftFiller . '</' . $name . ">\n";
    }

}

这篇关于用平面数据在PHP中构建分层html标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆