tags:

views:

40

answers:

1

for example, we have this xml:

<p>[TAG]
    <span>foo 1</span>
    <span>foo 2</span>
   [/TAG]
    <span>bar 1</span>
    <span>bar 2</span>
</p>

how can i detect <span>-tags between words [TAG] and [/TAG] ("foo 1" and "foo 2" in this case)?

UPD. for example i need to change nodeValue of each span between [TAG] and [/TAG]

+1  A: 

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();
Chris Smith
this `<p>[TAG] <span>foo 1</span> <span>[/TAG]</span></p>` and this `<p> <span>[TAG]</span> <span>foo 1</span>[/TAG]</p>` xml's can't be parsed only by xpath-query, right?
cru3l
@cru3l - Sure can. Just get rid of the `-sibling` in `preceding-sibling` and `following-sibling`.
Chris Smith
@cru3l : Correct. XPath works with nodes, not with "tags".
Dimitre Novatchev
@Dimitre But in all the given examples the "tags" inhabit their own text nodes, so we can quite happily use them in XPath queries
Chris Smith
@Chris-Smith: Not at all. If you look closely at the first comment by @cru3l above you'll see: `<p>[TAG] <span>foo 1</span> <span>[/TAG]`. As you can see, the last tag within is an unclosed `<span>`. This is not possible to "select" eith XPath.
Dimitre Novatchev