修改 DOM 以设置顺序标题的样式

Modifying DOM to style sequential headings

让我们从我的数据库 table 中的这个 html 开始:

<section id="love">
<h2 class="h2Article">III. Love</h2>
<div class="divArticle">

这是我通过 DOM 脚本 运行 后显示的样子:

<section id="love"><h2 class="h2Article" id="a3" data-toggle="collapse" data-target="#b3">III. Love</h2>
<div class="divArticle collapse in article" id="b3">

我希望它看起来像这样:

<section id="love"><h2 class="h2Article" id="a3" data- toggle="collapse" data-target="#b3">
    <span class="Article label label-primary">
        <i class="only-collapsed fa fa-chevron-down"></i>
        <i class="only-expanded fa fa-remove"></i> III. Love</span></h2>
<div class="divArticle collapse in article" id="b3">

换句话说,DOM 赋予了它必要的功能,正确地按顺序为每个 id 编号。缺少的只是样式:

<span class="Article"><span class="label label-primary"><i class="only- collapsed fa fa-chevron-down"></i><i class="only-expanded fa fa-remove"> </i> III. Love</span></span>

谁能告诉我如何添加该样式?当然,标题会改变(例如 III. Love,IV. Hate 等)。我在下面发布了我的 DOM 脚本:

$i = 1; // initialize counter
$dom = new DOMDocument;
@$dom->loadHTML($Content); // load the markup
$sections = $dom->getElementsByTagName('section'); // get all section tags
    foreach($sections as $section) { // for each section tag

        // get div inside each section
        foreach($section->getElementsByTagName('h2') as $h2) {
            if($h2->getAttribute('class') == 'h2Article') { // if this div has class maindiv
                $h2->setAttribute('id', 'a' . $i); // set id for div tag
                $h2->setAttribute('data-target', '#b' . $i);
            }
        }

        foreach($section->getElementsByTagName('div') as $div) {
            if($div->getAttribute('class') == 'divArticle') { // if this div has class divArticle
                $div->setAttribute('id', 'b' . $i); // set id for div tag
            }

            if($div->getAttribute('class') == 'divClose') { // if this div has class maindiv
                $div->setAttribute('data-target', '#b' . $i); // set id for div tag
            }
        }
        $i++; // increment counter
    }

// back to string again, get all contents inside body
$Content = '';
foreach($dom->getElementsByTagName('body')->item(0)->childNodes as $child) {
    $Content .= $dom->saveHTML($child); // convert to string and append to the container
}

$Content = str_replace('data-target', 'data-toggle="collapse" data-target', $Content);
$Content = str_replace('<div class="divArticle', '<div class="divArticle collapse in article', $Content);

由于在本例中使用了 DOM Document 对象,因此可以使用 createElement 函数添加 HTML.

http://php.net/manual/en/domdocument.createelement.php

并从附页上的文档中窃取

<?php

$dom = new DOMDocument('1.0', 'utf-8');

$element = $dom->createElement('test', 'This is the root element!');

// We insert the new element as root (child of the document)
$dom->appendChild($element);

echo $dom->saveXML();
?>

会输出

<?xml version="1.0" encoding="utf-8"?>
<test>This is the root element!</test>

如果没有 DOM 对象,您通常可以通过以下方式之一添加 PHP。

1.

echo "<div>this method is often used for shorter pieces of HTML</div>";

2.

?> <div> You can also escape out of HTML and then "turn" PHP back on like this </div> <?php

第一种方法使用echo命令输出一串HTML。第二种方法使用
?> 转义标记告诉计算机开始将所有内容视为 HTML 直到它看到另一个打开的 <?php PHP 标记。

所以通常在 PHP 文件中你可以像这样添加 HTML。

?> 
   <span class="Article">
       <span class="label label-primary">
           <i class="only- collapsed fa fa-chevron-down"></i>
           <i class="only-expanded fa fa-remove"></i> 
           III. Love
       </span>
    </span>
<?php

但是由于在这种情况下我们试图编辑来自数据库内部的内容,所以我们无法执行此操作。

好吧,我想显而易见的解决方案是将标题包裹在可以用简单的 str_replace...

修改的内容中
<h2><span class="Answer">IIII. Love</span></h2>

甚至这个...

<h2>[]III. Love[]</h2>

有点像米老鼠,但它完成了工作。我只需将所有这些代码写出或粘贴到每篇文章的每个标题中。我更喜欢尽可能自动化它。