Osama Abuhamdan
Osama Abuhamdan

Reputation: 179

Get everything before a specific node with XPath

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

Answers (2)

kjhughes
kjhughes

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

Daniel Haley
Daniel Haley

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

Related Questions