Home > Software engineering >  XPath: Trying to filter based on multiple child nodes
XPath: Trying to filter based on multiple child nodes

Time:07-21

I have this XML:

<doc>
  <target>
    <name>V1</name>
    <value>3</value>
  </target>
  <var>
    <name>V1</name>
    <value>1</value>
  </var>
  <var>
    <name>V2</name>
    <value>3</value>
  </var>
</doc>

I want an XPath query that returns all target nodes where there exists a var node with whose name and value nodes match those specified in the target. In the example above, there should be no matches.

My attempts at a query look something like this:

//target[//var/name=name and //var/value=value]

This query returns the target node because there exists a variable V1, and there exists a variable whose value is 3. But this is not what I am after; I only want matches where the name and the value of the same variable match the target.

I'm using XPath 1.0, so techniques to accomplish this with that version would be most helpful.

CodePudding user response:

If doc has multiple var nodes but one target only you can try

//doc[var[name=preceding-sibling::target/name and value=preceding-sibling::target/value]]/target

CodePudding user response:

XPath 1.0 is not relationally complete (see https://www.rjerz.com/c/infosys/support/Codd-Relational_Completeness_Article.pdf) which means that not all join queries can be expressed, and I think this is one that can't. The limitation arises because XPath 1.0 has no range variables.

In XPath 2.0 it's easy:

//target[some $v in //var satisfies name=$v/name and value=$v/value]

CodePudding user response:

Not sure you can do exactly what you want with xpath 1.0 but you can sort of fake it by using the text of the <var> nodes to compare to that of <target>. So

//target[normalize-space(.)=//var/normalize-space(.)]

should do it: it will show no match with your sample xml. If you change the <name> value in the last <var> to V1 it should show one match.

  • Related