6

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
  • 1
    What do you mean by "it isn't happy with it"? Commented Jan 23, 2012 at 18:34

6 Answers 6

20

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 + "')]");
Sign up to request clarification or add additional context in comments.

Comments

5

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

Comments

2

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

Comments

2

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.

Comments

0

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

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.