0

I would like to know if there is a way to obtain the value of the origin node when doing a query.

I have an XPath query using selectSingleNode. I would like to be able to create a predicate where the test is against a value from the node being searched.

For example...

node.selectSingleNode("//node1/node2[anotherNode=origin()/originNode]/theReturningNode")

The origin() in this case is the node used in the selectSingleNode

Many Thanks

James Hutchison
  • 63
  • 1
  • 1
  • 8
  • I guess you're using the DOM method node.selectSingleNode() and therefore you're probably using XPath 1.0. There are certainly solutions if you switch to an XPath processor that implements a more up-to-date version of XPath. – Michael Kay Dec 05 '19 at 12:46

2 Answers2

2

There is such a thing in XSLT (called current()), but it does not exist in XPath.

You have to build your XPath expression dynamically in this case:

"//node1/node2[anotherNode = '" + originNode.text + "']/theReturningNode"

Beware that this will produce invalid XPath (and therefore run-time errors) when originNode.text contains single quotes. This can be worked around if necessary. Different work-arounds apply to XPath 1.0 and 2.0.

Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • Yes, we're aware of that...and I assumed there was no means to do this, but wanted to confirm this was 100%. – James Hutchison Dec 05 '19 at 12:54
  • Also be aware that constructing an XPath expression using string concatenation exposes you to injection attacks. It's better if you can to use a variable, and supply the variable's value using an API. – Michael Kay Dec 05 '19 at 12:56
  • This is not always possible, but when it is, it's of course the preferred approach. – Tomalak Dec 05 '19 at 14:43
1

If you install an XPath processor such as Saxon that implements an up-to-date version of XPath, then you can use the query

let $origin := . return
    //node1/node2[anotherNode=$origin/originNode]/theReturningNode

In fact some XPath 1.0 processors will allow you to run the query

//node1/node2[anotherNode=$origin/originNode]/theReturningNode

supplying the value of $origin as an external parameter via API.

You probably won't be able to use the DOM's selectSingleNode method, but other APIs are available (e.g. JAXP).

Michael Kay
  • 156,231
  • 11
  • 92
  • 164