Pavel V
Pavel V

Reputation: 1

XPath: how to iterate all text nodes?

Please tell me how to iterate through all text nodes inside a paragraph? After all, they can be 2-3 level.

For example, take the following paragraph:

<p>Lorem <i>ipsum dolor</i> sit <span>amet, <b><i>consectetur</i> adipisicing</b> elit</span>. Odit, sunt?</p>

In which you want to process all text nodes and return them to their places.

$content = '<p>Lorem <i>ipsum dolor</i> sit <span>amet, <b><i>consectetur</i> adipisicing</b> elit</span>. Odit, sunt?</p>';

$html = new DOMDocument();
$html->loadHTML($content);

$xpath = new DOMXpath($html);

$elements = $xpath->query('//descendant-or-self::p//node()');

  // My processor (not working...)

  foreach ($elements as $element) {

    // Processed, only text nodes (not working...)
    if ( $element->nodeType == 3 ) {
      function() {
        return $element->nodeValue = '<span style="background-color: yellow;">' . $element->nodeValue . '</span>';
      }
    }
    // return to the place
    echo $element->C14N();

  }

You need to get such result:

<p>
<span style="background-color: yellow;">Lorem </span>
<i>
<span style="background-color: yellow;">ipsum dolor</span>
</i>
<span style="background-color: yellow;">sit </span>
<span>
<span style="background-color: yellow;">amet, </span>
<b><i>
<span style="background-color: yellow;">consectetur</span>
</i>
<span style="background-color: yellow;">adipisicing</span>
</b>
<span style="background-color: yellow;">elit</span>
</span>
<span style="background-color: yellow;">. Odit, sunt?</span>
</p>

Upvotes: 0

Views: 625

Answers (1)

Gordon
Gordon

Reputation: 316969

This will wrap all the text nodes into span elements:

$content = '<p>Lorem <i>ipsum dolor</i> sit <span>amet, <b><i>consectetur</i> adipisicing</b> elit</span>. Odit, sunt?</p>';

$html = new DOMDocument();
$html->loadHTML($content);

$xpath = new DOMXpath($html);

$elements = $xpath->query('//descendant-or-self::p//text()');
/* @var DomNode $element*/
foreach ($elements as $element) {
    $span = $html->createElement("span", $element->nodeValue);
    $span->setAttribute("style", "background-color: yellow;");
    $element->parentNode->replaceChild($span, $element);
}

echo $html->saveHTML();

Upvotes: 1

Related Questions