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.