问题
How can I execute following queries on the given xml:
- if(task1=cde && task2=abc) I would get id=XYZ-987
- if((task1=abc && task2=efg) || task5=nop) I would get id=ABC-123,XYZ-987,RST-567
XML here:
<node1>
<node2>
<node3>
<id>ABC-123</id>
<condition>
<task name="task1" operation="and" value="abc" />
<task name="task2" operation="and" value="efg" />
<task name="task3" operation="and" value="hij" />
<task name="task4" operation="or" value="klm" />
<task name="task5" operation="and" value="nop" />
<task name="task6" value="uvw" />
</condition>
</node3>
<node3>
<id>XYZ-987</id>
<condition>
<task name="task1" operation="and" value="cde" />
<task name="task2" operation="and" value="abc" />
<task name="task5" operation="and" value="nop" />
</condition>
</node3>
<node3>
<id>RST-567</id>
<condition>
<task name="task1" operation="and" value="abc" />
<task name="task2" operation="and" value="efg" />
<task name="task8" operation="and" value="jkl" />
<task name="task9" operation="and" value="rst" />
<task name="task10" value="xyz" />
</condition>
</node3>
<node3>
<id>PQR-345</id>
<condition>
<task name="task1" operation="and" value="ijk" />
<task name="task2" operation="and" value="klm" />
<task name="task8" operation="and" value="jkl" />
<task name="task9" operation="and" value="rst" />
</condition>
</node3>
</node2>
</node1>
I tried the following rule but I get empty result
String expression = "/node1/node2/node3/id[following-sibling::condition/task[(@name='task1' and @value='cde') and (@name='task2' and @value='abc')]]"
I got the above expression from How to parse XML using XPATH
What would be the expression for above 2 cases?
回答1:
The reason why your xpath doesn't work is because your predicate [(@name='task1' and @value='cde') and (@name='task2' and @value='abc')] executes on the same task node, and if @name='task1' then @name can never be = 'task2'.
Instead you should create predicates that will operate on/check all the relevant nodes like this:
1.
if(task1=cde && task2=abc) I would get id=XYZ-987
/node1/node2/node3[condition/task[@name='task1' and @value='cde'] and condition/task[@name='task2' and @value='abc']]/id
2.
if((task1=abc && task2=efg) || task5=nop) I would get id=ABC-123,XYZ-987,RST-567
/node1/node2/node3[condition/task[@name='task1' and @value='abc'] and condition/task[@name='task2' and @value='efg'] or condition/task[@name='task5' and @value='nop']]/id
you can include your brackets if you want, but in boolean operations, and arguments are always evaluated before or arguments, so they are unnecessary in this case:
/node1/node2/node3[(condition/task[@name='task1' and @value='abc'] and condition/task[@name='task2' and @value='efg']) or condition/task[@name='task5' and @value='nop']]/id
来源:https://stackoverflow.com/questions/35620660/xpath-executing-complex-queries