0

I am trying to select the second node() but only if it is a text node.

<p><span>Span text</span> plain text</p> 

I have tried /p/node()[2]/text() but that doesn't work because there isn't a text node inside the second node. /p/node()[1]/text() gives 'Span text' and /p/text()[1] gives ' plain text' but it should be using [2] somewhere instead of [1]. I can't work out how you specify a text predicate after you've selected the node.

The result I want is something like:

NodeList { length => 2, 0 => Node('<span>Span text</span>'), 1 => Text(' plain text') } 

where the first node must be a span and the second node must be text only. Preferably, there shouldn't be any other nodes so if there were more than two it shouldn't match anything and if the text node is missing it shouldn't match the span node.

/p/node()[1]|/p/node()[2] returns what I want when the input is good but it also returns matches outside of my requirements. e.g:

<p>Bad match <span>Span text</span> plain text</p> 

would return 'Bad match ' as node()[1]. This example of an invalid match should return the following:

NodeList { length => 0 } 
2
  • Look here: stackoverflow.com/questions/5033955/xpath-select-text-node. I believe the syntax for your example would be /p/text(): select all text node children under "p". Commented Aug 16, 2014 at 6:32
  • But how do I know the text node is the second child? That expression matches all the text children, regardless of their position. Commented Aug 16, 2014 at 7:21

1 Answer 1

1

How about something like this :

/p[node()[2] = text()] 

That will select <p> with the 2nd child node equal to a text child node. Then you can continue the path by selecting any desired child of the <p>, for example :

/p[node()[2] = text()]/node()[1]|/p[node()[2] = text()]/node()[2] 
Sign up to request clarification or add additional context in comments.

1 Comment

Excellent answer! I've expanded slightly on it: p[count(node())=2][node()[1]=span][node()[2]=text()]/node() but it's much better (and easier to read) than the solution I eventually came up with. A gold star for you!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.