Reputation: 179
I got the following XML content
<root>
<node1>Hi from node 1</node1>
text not encapsulated in node
<node2>Hi from node 2</node2>
<node3>content....<node3/>
</root>
The question is : how to get all content before node3, even those not encapsulated in a node using XPath version 1.0 or 2.0 ?
Upvotes: 3
Views: 752
Reputation: 111726
This XPath,
/root/node3/preceding-sibling::node()
will select all of the nodes, not just elements, preceding node3
as siblings:
<node1>Hi from node 1</node1>
text not encapsulated in node
<node2>Hi from node 2</node2>
If you really want the content of all previous sibling nodes, see @DanielHaley's fine answer, or use (also XPath 2.0):
/root/node3/preceding-sibling::node()/string()
yielding:
Hi from node 1
text not encapsulated in node
Hi from node 2
Use normalize-space()
in place of string()
to normalize whitespace:
Hi from node 1 text not encapsulated in node Hi from node 2
Note that these return multiple strings (which may be concatenated in context) whereas Daniel Haley's XPath expression will directly return a single string, which may be more directly what you want.
Upvotes: 5
Reputation: 52888
Since you can use XPath 2.0, I'd use a combination of string-join() and normalize-space()...
string-join(//text()[following::node3]/normalize-space(),' ')
returns...
Hi from node 1 text not encapsulated in node Hi from node 2
Upvotes: 2