Как установить класс для всех родителей текстового узла внутри определенного блока - PullRequest
0 голосов
/ 02 марта 2019

Мне нужно установить класс для родительского элемента каждого текстового узла внутри определенного блока на моей странице.

Вот что я пытаюсь сделать:

$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, но я не получаю.

Как я понимаю, мне нужно вернуть измененных родителей в DOM после установки классаим, но как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

Хорошо, я нашел ответ сам:

...
$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');
            }
        }
    }
}
0 голосов
/ 02 марта 2019

Попробуйте этот код, вы должны получить узел по его имени, используя 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();
...