How to get all streaming text content in XML using XPath
XML file
<TEXT>
<DESCR>
Here is the first part...
<PLUS>The second</PLUS>
And the third
</DESCR>
</TEXT>
What I expect to get:
Here is the first part...The secondAnd the third
What I actually get:
Here is the first part...And the third.
I tried descendant-or-self::*
the xPath function, child and stream, with no result.
If anyone can tell me how to get text in child nodes too.
XPath 1.0
You cannot do concatenation of all text descendants of a given node in XPath 1.0. You can select nodes in XPath,
/TEXT/DESCR//text()
but then you have to do the concatenation in the hosting language.
In PHP:
$xml = '<TEXT>
<DESCR>
Here is the first part...
<PLUS>The second</PLUS>
And the third
</DESCR>
</TEXT>';
$dom = new DOMDocument();
$dom->loadXML($xml);
$x= new DOMXpath($dom);
foreach($x->query("/TEXT/DESCR//text()") as $node) echo trim($node->textContent);
Will output the result you requested:
Here is the first part...The secondAnd the third
[Otherwise, unless you have any other reason to iterate over the text nodes, replace the loop foreach
above:]
$xml = '<TEXT>
<DESCR>
Here is the first part...
<PLUS>The second</PLUS>
And the third
</DESCR>
</TEXT>';
$dom = new DOMDocument();
$dom->loadXML($xml);
$x= new DOMXpath($dom);
echo str_replace(PHP_EOL, '', $x->evaluate('normalize-space(/TEXT/DESCR)'));
What gives:
Here is the first part... The second And the third
XPath 2.0
You can concatenate all text descendants of a given node in XPath 2.0:
string-join(/TEXT/DESCR//text(), '')
If you cannot change your input XML, this might work:
concat(/TEXT/DESCR,/TEXT/DESCR/PLUS)
or
string-join(/TEXT/DESCR/descendant-or-self::text())