I’m using C# and .NET 2.0.
Given the XML below, I’d like to get a XMLNodeList of <user> nodes where the <role> is “admin”.
<users>
<user>
<name>John Doe</name>
<roles>
<role>superadmin</role>
<role>admin</role>
</roles>
</user>
<user>
<name>Jane Doe</name>
<roles>
<role>superadmin</role>
<role>admin</role>
</roles>
</user>
<user>
<name>Rob Doe</name>
<roles>
<role>support</role>
</roles>
</user>
</users>
Assume roleName = “admin”. This works, but is case-sensitive.
userNodesForRole = _document.SelectNodes("//users/user[roles[role='" + roleName + "']]");
I want to do it in a case-insensitive fashion. I know I can’t use the matches function because .NET 2.0 (and maybe higher?) doesn’t support XPath 2.0. So I did this:
// abc...xyz is the string literal of the entire alphabet, of course
userNodesForRole = _document.SelectNodes("//users/user[roles[translate(role,'abc..xyz','ABC...XYZ')='" + roleName.ToUpper() + "']]", _xmlNamespaceManager);
However, I don’t get any nodes back. Can someone please tell me what I’m getting wrong?
This evaluates an XPath expression like the following:
and the above XPath expression when evaluated on the provided XML document:
selects the following nodes:
The XPath expression will not select the wanted elements if there is a
roleselement that has more than onerolechild and a<role>admin</role>element is not the firstrolechild of its parent.An XPath expression that selects the desired elements even in this case is;
There may be a variety of reasons why the first expression raises an exception or doesn’t select the wanted nodes. To find out the exact reason, print the constructed XPath expression and provide it here.
Update: @ck has now provided his real XML document and indeed, in the real XML document the
rolechildren (<role>admin</role>elements ) arenot the firstrolechild of their parent.So my guess and explanation was correct.