Reputation: 68046
Example of markup:
<p> a paragraph </p>
<pre lang="html">
<p> a paragraph </p>
</pre>
<code lang="html">
<p> a paragraph </p>
</code>
How can I select all the stuff between <pre>
,</pre>
,<code>
,</code>
and run a function on it? Trough this function I need to pass 3 arguments: the part of the string that's selected (<p> a paragraph </p>
), the container type (pre
or code
), and the parameters of the container (like lang="html"
).
The function should change the selected part of the string based on the other 2 parameters (if it's relevant I want run the GeShi highlighter on it), then replace the contents of the original string with it, including the container. Something like:
<p> a paragraph </p>
<div class="html pre">
<p> a paragraph </p>
</div>
<div class="html code">
<p> a paragraph </p>
</div>
Upvotes: 3
Views: 699
Reputation: 67715
I think it should go like this:
$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$elements = $xpath->query('//pre | //code');
In some cases (e.g.: if you use getElementsByTagName instead of XPath), you will need to operate on an array to get the proper behaviour (see this question), so you need to copy the nodes to an array. I'll do it for this example:
$array = array();
foreach ($elements as $element) {
$array[] = $element;
}
foreach ($array as $element) {
$tag = $element->tagName;
$content = $element->textContent;
$lang = $element->getAttribute('lang');
$new_content = my_function($tag, $content, $lang);
$new_element = $dom->createElement('div');
$new_element->setAttribute('class', "$tag $lang");
$new_element->nodeValue = $new_content;
$element->parentNode->replaceChild($new_element, $element);
}
Of course, in the example above, the my_function
is undefined. But it should give you a good idea on the howto.
Note that this won't work on nested elements, like these:
<pre lang="html">
<p>some nested element</p>
<p> a paragraph </p>
</pre>
If you want to work on nested elements, use a function to get the innerHTML instead of using $element->textContent
.
Upvotes: 3