XPath lower-case() function

13,083

Solution 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 + "')]");

Solution 2

translate(../location, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') if you can get away with just A-Z

Solution 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));.

Solution 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.

Share:
13,083

Related videos on Youtube

Luke
Author by

Luke

I'm a keen website and software developer. I am particularly knowledgeable in C#, .NET Core, WebAPI, HTML, CSS/SCSS, JavaScript, Powershell, Webpack and AWS.

Updated on June 04, 2022

Comments

  • Luke
    Luke almost 2 years

    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.

    • BoltClock
      BoltClock about 12 years
      What do you mean by "it isn't happy with it"?