问题
I'm using XPATH to select certain nodes from an XML document.
The user is able to insert a value for the location. It's working fine, but it does not work if different cases are used.
I've decided that changing both the XML values and the user's input to lower case before being compared is probably the best way to go about it.
I've got this as my selector at the moment:
NodeIter = nav.Select("/Houses/House/location[contains(../location, '" + location_input + "')]");
I've tried putting the lower-case() function in various locations, but it isn't happy with it.
How do I make it so that the value of ../location is compared as lower case?
Note: location_input is set to lower using ToLower() within my c# code.
回答1:
The lower-case() function is only supported from XPath 2.0 onwards. If your environment supports this version of the standard, you can write:
NodeIter = nav.Select("/Houses/House/location[contains(lower-case(.), '"
+ location_input + "')]");
However, chances are you're stuck with XPath 1.0. In that case, you can abuse the translate() function:
NodeIter = nav.Select("/Houses/House/location[contains(translate(., "
+ "'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '"
+ location_input + "')]");
回答2:
translate(../location, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') if you can get away with just A-Z
回答3:
lower-case http://www.w3.org/TR/xpath-functions/#func-lower-case is part of XPath 2.0 and XQuery 1.0 so you need to use an XPath 2.0 or XQuery 1.0 implementation like XQSharp or like the .NET version of Saxon 9 if you want to use such functions.
With XPath 1.0 all you can do is NodeIter = nav.Select(string.Format("/Houses/House/location[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXZY', 'abcdefghijklmnopqrstuvwxyz'), '{0}')]", location_input));.
回答4:
Note that strictly speaking, translating two strings to lower (or upper) case is not a correct way to do a case-blind comparison, because the mapping of lower-case to upper-case characters in Unicode is not one-to-one. In principle, in XPath 2.0 you should use a case-blind collation. Unfortunately though, although many XSLT 2.0 and XQuery 1.0 processors allow you to use a case-blind collation, there are no standards for collation URIs, so your code becomes processor-dependent.
回答5:
As long as you are dealing with .net, you can use a Microsoft extension to do a case-insensitive comparison: ms:string-compare
https://msdn.microsoft.com/en-us/library/ms256114(v=vs.120).aspx
回答6:
I had same dilemma using VS2017(NetFramework 4.6.1) and installed the XPath2 NuGet package. So far it has been worked fine for me when using XPath2 functions.
来源:https://stackoverflow.com/questions/8976570/xpath-lower-case-function