在php中列出H2-H3元素

时间:2016-10-25 13:56:38

标签: php html string dom

我有一个PHP变量,其中包含我的页面的HTML代码,仅包含段落和H2-H3元素:

<ul>
    <li>Header 1
      <ul>
          <li>Sub-header 1</li>
      </ul>
    </li>
    <li>Header 2
      <ul>
          <li>Sub-header 2</li>
          <li>Sub-header 3</li>
      </ul>
    </li>
    <li>Header 3</li>
</ul>

我正在尝试创建一个函数,该函数使用HTML代码获取变量并返回带有HTML ul列表的字符串:

function generate_navigation($HTML) {
    $DOM = new DOMDocument();
    $DOM->loadHTML($HTML);

    $navigation = '<ul>';

    // Iterating through all elements
    $h2Iterator = 0;
    foreach($DOM->getElementsByTagName('*') as $element) {
        if($element->tagName == 'h2') {
            $h2Iterator++;
            $navigation .= '<li>' . $element->textContent . '</li>';
        } else if ($element->tagName == 'h3') {
            // How to add?
        }
    }

    return $navigation.'</ul>';
}

这里我取得了什么,但我坚持检测何时添加sub-ul标签以及如何执行此操作:

{{1}}

2 个答案:

答案 0 :(得分:2)

您需要跟踪打开的h2标签。不需要迭代器计数器,但需要迭代器状态。

function generate_navigation($HTML) {
    $DOM = new DOMDocument();
    $DOM->loadHTML($HTML);

    $navigation = '<ul>';

    // Iterating through all elements
    $h2IteratorStatus = 0; //0-closed, 1-open
    $h3IteratorStatus = 0; //0-closed, 1-open
    foreach($DOM->getElementsByTagName('*') as $element) {
        if($element->tagName == 'h2') {

            if($h3IteratorStatus){
                //it's open, need to close
                $navigation .= '</ul>';
                $h3IteratorStatus = 0;
            }

            if($h2IteratorStatus){
                //it's open, need to close
                $navigation .= '</li>';
                $h2IteratorStatus = 0;
            }

            $h2IteratorStatus = 1;
            $navigation .= '<li>' . $element->textContent ;

        } else if ($element->tagName == 'h3') {

            if(!$h3IteratorStatus){
                $navigation .= '<ul>';
                $h3IteratorStatus = 1;
            }

            $navigation .= '<li>' . $element->textContent .'</li>';
        }
    }

    //check for last opened h3
    if($h3IteratorStatus){
        $navigation .= '</ul>';
    }
    //check for last opened h2
    if($h2IteratorStatus){
        //it's open, need to close
        $navigation .= '</li>';
    }

    return $navigation.'</ul>';
}

根据您的评论更新,以跟踪已打开的h3标记。

答案 1 :(得分:0)

我做到了:

$dom = new domDocument;
$dom->loadHTML( $html );

$nav   = [];
$index = 0;

foreach ( $dom->getElementsByTagName('*') as $elem )
{
    if ( 'h2' == $elem->tagName )
    {
        $index++;
        $nav[ $index ]['h2'] = $elem->textContent;
    }


    if ( 'h3' == $elem->tagName )
    {
        $nav[ $index ]['h3'][] = $elem->textContent;
    }
}

会产生类似下面的内容,这应该更容易使谷底循环

Array
(
    [1] => Array
        (
            [h2] => Headline Section
        )

    [2] => Array
        (
            [h2] => Headline Section
            [h3] => Array
                (
                    [0] => Sub-Section
                )

        )

    [3] => Array
        (
            [h2] => EstLaborum sunt incididunt
            [h3] => Array
                (
                    [0] => Sub-Section
                )

        )

)```