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
}
CJ Dennis
  • 4,226
  • 2
  • 40
  • 69
  • Look here: http://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". – FoggyDay Aug 16 '14 at 06:32
  • But how do I know the text node is the second child? That expression matches all the text children, regardless of their position. – CJ Dennis Aug 16 '14 at 07:21

1 Answers1

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]
jpaugh
  • 6,634
  • 4
  • 38
  • 90
har07
  • 88,338
  • 12
  • 84
  • 137
  • 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! – CJ Dennis Aug 16 '14 at 07:32