如何为特定块内的所有文本节点父级设置类

时间:2019-03-02 10:03:21

标签: php domdocument

我需要将一个类设置为页面上特定块内每个文本节点的父级。

这就是我想要做的:

$pageHTML = '<html><head></head>
<body>

<header>
  <div>
    <nav>Menu</nav>
    <span>Another text</span>
  </div>
</header>

<section>Section</section>
<footer>Footer</footer>
</body>
</html>';

$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTML($pageHTML);
libxml_use_internal_errors(false);

foreach($dom->getElementsByTagName('body')[0]->childNodes as $bodyChild) {

    if($bodyChild->nodeName == 'header') {

        $blockDoc = new DOMDocument();
        $blockDoc->appendChild($blockDoc->importNode($bodyChild, true));
        $xpath = new DOMXpath($blockDoc);

        foreach($xpath->query('//text()') as $textnode) {
            if(preg_match('/\S/', $textnode->nodeValue)) { // exclude non-characters
                 $textnode->parentNode->setAttribute('class','my_class');
            }
        }
    }
}

echo $dom->saveHTML((new \DOMXPath($dom))->query('/')->item(0));

我需要使用<nav><span>内的<header>my_class放入local lgi = require 'lgi' local GLib, Gio = lgi.GLib, lgi.Gio local main_loop = GLib.MainLoop() --Get a system bus local bus = Gio.bus_get_sync(Gio.BusType.SYSTEM) --Create a user callback function that needs to operate when signal is received function onDBusSignalCallback(conn, sender, object_path, interface_name, signal_name, user_data) local str = string.format("SIGNAL - object_path:%s, interface_name:%s, signal_name:%s", object_path, interface_name, signal_name) print(str) end --Subscribe to any signal. local sub_id = bus:signal_subscribe('org.bluez', 'org.freedesktop.DBus.Properties', 'PropertiesChanged', nil, nil, Gio.DBusSignalFlags.NONE, onDBusSignalCallback) if sub_id then print("Subscription id", sub_id) end main_loop:run() 内,但我不知道。

据我了解,在将类设置为父类之后,我需要将更改后的父类返回给DOM,但是我该怎么做呢?

2 个答案:

答案 0 :(得分:1)

好的,我自己找到了答案:

...
$xpath = new DOMXpath($dom);

foreach($dom->getElementsByTagName('body')[0]->childNodes as $bodyChild) {

    if($bodyChild->nodeName == 'header') {

        foreach($xpath->query('.//text()', $bodyChild) as $textnode) {

            if(preg_match('/\S/', $textnode->nodeValue)) { // exclude non-characters
                $textnode->parentNode->setAttribute('class','my_class');
            }
        }
    }
}

答案 1 :(得分:0)

尝试使用此代码,您必须使用getElementsByTagName而不是通过文本节点来检查其名称。

$pageHTML = '<html>
<head></head>
<body>

<header>
  <div>
    <nav>Menu</nav>
    <span>Another text</span>
  </div>
</header>

<section>Section</section>
<footer>Footer</footer>
</body>
</html>';

$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTML($pageHTML);
libxml_use_internal_errors(false);

$elements = $dom->getElementsByTagName('header');
foreach ($elements as $node) {
    $nav = $node->getElementsByTagName('nav');
    $span = $node->getElementsByTagName('span');

    $nav->item(0)->setAttribute('class', 'my_class');
    $span->item(0)->setAttribute('class', 'my_class');
 }

echo $dom->saveHTML();