Assuming that you only have one set of [TAG]..[/TAG]
per node (as in, if your document has two sets they're within separate <p>
elements or whatever), and that they're always siblings:
You can use preceding-sibling
and following-sibling
to select only elements which are preceded by a [TAG] text node and followed by a [/TAG] text node:
//span[preceding-sibling::text()[normalize-space(.) = "[TAG]"]][following-sibling::text()[normalize-space(.) = "[/TAG]"]]
A full PHP example:
$doc = new DOMDocument();
$doc->loadHTMLFile('test.xml');
$xpath = new DOMXPath($doc);
foreach ($xpath->query('//span[preceding-sibling::text()[normalize-space(.) = "[TAG]"]][following-sibling::text()[normalize-space(.) = "[/TAG]"]]') as $el) {
$el->nodeValue = 'Changed!';
}
echo $doc->saveXML();