I've got an XPath expression with a predicate that selects a person's name and ID from within a nested element, using the XPathNavigator.Select method.
This works:
root/all_clients/client/client_name_and_ID[client_ID = 'xxx']
This also works:
root/all_clients/client[client_name_and_ID/client_ID = 'xxx']/client_name_and_ID
When I take the predicate to the next level, it does not work:
root/all_clients[client/client_name_and_ID/client_ID = 'xxx']/client/client_name_and_ID
I do not get any filtering, but the entire set.
Is this due to a limitation inherent within XPath, within ASP.NET, or am I doing something stupid?
What follows is a snippet from the relevant XML file:
<?xml version="1.0" encoding="utf-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="file:///n:\Projects\XML\Medical\Example_01.xsd">
<all_clients>
<client>
<client_name_and_ID>
<first_name>Fred</first_name>
<middle_name>James</middle_name>
<last_name>Bowman</last_name>
<client_ID>1</client_ID>
</client_name_and_ID>
</client>
<client>
<client_name_and_ID>
<first_name>Mark</first_name>
<middle_name>David</middle_name>
<last_name>Colder</last_name>
<client_ID>2</client_ID>
</client_name_and_ID>
</client>
<client>
<client_name_and_ID>
<first_name>Joe</first_name>
<last_name>Lewis</last_name>
<client_ID>3</client_ID>
</client_name_and_ID>
</client>
<client>
<client_name_and_ID>
<first_name>Sam</first_name>
<last_name>Plank</last_name>
<client_ID>4</client_ID>
</client_name_and_ID>
</client>
</all_clients>
</root>
The last query is matching an all_clients element that contains any matching client underneath it. It then selects clients under this all_clients without the filter applied, so it selects all of the client elements.
You should save the filter for the end of the XPath. First select down to the type of element you want, and then apply a filter to those elements. Try these XPaths:
<!-- Select client_ID element. -->
root/all_clients/client/client_name_and_ID/client_ID[. = 'xxx']
<!-- Select client_name_and_ID element. -->
root/all_clients/client/client_name_and_ID[client_ID = 'xxx']
<!-- Select client element. -->
root/all_clients/client[client_name_and_ID/client_ID = 'xxx']