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"
x开发者_如何学编程si: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']
That's normal. All client
nodes are children of the all_clients
node. Therefore it will always qualify to the condition "all elements named all_clients
having at least one match of a descendant client/client_name_and_ID/client_ID = 'xxx'
" which is what you have coded.
精彩评论