4

I am trying to implement case insensitive search using XPath. I have already referred how to perform a case-insensitive attribute selector in xquery so please check before marking as duplicate. I am using Lcase to convert my variable (L_search) to lowercase and lower-case functions.

My original case sensitive XPath expression is:

XPath       =  "//*[contains(., '"& search &"')]/ancestor-or-self::*/*[local-name()='home' and @locale='en']"

I have tried many combinations like :

XPath       =  "//*lower-case([contains(., '"& L_search &"')])/ancestor-or-self::*/*[local-name()='home' and @locale='en']"

XPath       =  "//*[contains(lower-case(.), '"& L_search &"')])/ancestor-or-self::*/*[local-name()='home' and @locale='en']"

But none of them is yielding a result.

This is the code I'm running:

Sub ProcessFolder(FolderPath)
    On Error Resume Next
    Set fldr = fso.GetFolder(FolderPath)

    Set Fls = fldr.files
    For Each thing in Fls
            sFSpec = FSO.GetAbsolutePathName(thing)
            objMSXML.async = True
            objMSXML.load sFSpec
             If 0 = objMSXML.parseError Then
                Dim sXPath   : sXPath       =  "//*[contains(., '"& search &"')]/ancestor-or-self::*/*[local-name()='name' and @locale='en']"

                Dim querySubject : Set querySubject = objMSXML.selectSingleNode(sXPath)
                    Set p = document.createElement("p")
                        p.innerText = thing.Path
                        document.body.appendChild p
                    If querySubject Is Nothing Then
                        MsgBox sXPath, "failed"
Community
  • 1
  • 1
Kailash Singh
  • 405
  • 2
  • 7
  • 12
  • 1
    As is, your question is hardly answerable. What XQuery implementation are you using, does it support XQuery 3.0? Do you actually use XQuery, as you're calling the strings "XPath", which is only a subset? Please generally provide reproducible examples, which includes input and expected output. I'm voting to close your question as being incomplete, please edit it with the required details (which will stop the closure process). – Jens Erat Apr 04 '16 at 16:39
  • Edited and added code snippet.... I dont know about 3.0 support but this xpath code is working fine for me. – Kailash Singh Apr 04 '16 at 19:58
  • 1
    I've [shown you how to do case-insensitive matching](http://stackoverflow.com/a/36408190/290085) per your question title. If you need further help, please read [ask], explain your comment where you say *this xpath code is working fine for me* (so your question is answered?), and if you still have a question, create a [mcve]. Thanks. – kjhughes Apr 04 '16 at 20:23
  • In fact I missed something, My mistake..... Thanks a ton @kjhughes – Kailash Singh Apr 04 '16 at 20:27
  • So, your question is answered? What was the answer? – kjhughes Apr 04 '16 at 20:28
  • 1
    Your posted code looks like VBScript using MSXML which does only support XPath 1.0 but certainly no version of XQuery. – Martin Honnen Apr 04 '16 at 20:37
  • 2
    The question looks much better now, and you added very relevant information. Please be aware you're not having any support for XQuery, and are stuck with the very bare-bones XPath 1.0. The `translate(...)` solution already provided as an answer is the only possible for you, although it is not very elegant. XQuery is a much more powerful superset of XPath, but has pretty much no direct language support and requires embedding or interfacing some library that provides XQuery integration. – Jens Erat Apr 04 '16 at 21:06
  • @JensErat Thanks a lot for your kind elaborating of the differences....I will definitely read about Xpath and Xquery now. Thanks a lot. It was my mistake, I was unable to get right answer due to.... – Kailash Singh Apr 04 '16 at 21:10
  • 1
    After thrashing through what's really being asked here, how to do case-insensitive `contains()` is really just a duplicate of [**case insensitive xpath contains() possible?**](http://stackoverflow.com/q/8474031/290085) – kjhughes Apr 04 '16 at 21:20
  • 1
    Possible duplicate of [case-insensitive matching in xpath?](http://stackoverflow.com/questions/2893551/case-insensitive-matching-in-xpath) – user692942 Apr 04 '16 at 23:00

2 Answers2

9

VBScript supports only XPath 1.0 and not XQuery, so first edit your question title.

In XPath 1.0 the translate() function is used for case insensitivity.

//*[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') , search)]/ancestor-or-self::*/*[local-name()='home' and @locale='en']

Where search = Lcase(V_SAEARCH)

It will work perfect. No need to use quotes around your variable.

another way to write this is:-

//*[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') , translate('" & search & "', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'))]/ancestor-or-self::*/*[local-name()='home' and @locale='en']

Here search variable is being translated in XPath.

user2816085
  • 655
  • 4
  • 19
  • Thanks, I am a beginner, so no Idea that there are versions and all........ Thanks a lot it worked perfectly. – Kailash Singh Apr 04 '16 at 21:04
  • If `search` is to be interpreted as an variable name, would not the XPath will have to be constructed via string concatenation so that `search` is not interpreted in XPath as an element name? – kjhughes Apr 04 '16 at 21:24
  • No need of string concatanation to 'search', it is needed inside contains() only..... It is giving right result. – Kailash Singh Apr 04 '16 at 21:35
  • still inside contains() but not needed to concatanate. – Kailash Singh Apr 04 '16 at 21:37
  • @KailashSingh: Is `search` a variable from outside of XPath or an element name in your XML? – kjhughes Apr 05 '16 at 11:57
  • here search is a variable containing search term in lower case Lcase(v_search). Lcase is vbscript function – user2816085 Apr 09 '16 at 18:58
  • //*[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') , translate('" & search & "', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'))]/ancestor-or-self::*/*[local-name()='home' and @locale='en'] – user2816085 Apr 09 '16 at 19:01
3

XPath 2.0

If you use case-insensitive matches(),

"//*[matches(., '"& search &"', 'i')]/ancestor-or-self::*/*[local-name()='home' and @locale='en']"

you won't need to worry about the case of your search variable.


See also case insensitive xpath contains() possible? for other XPath 1.0 and 2.0 solutions.

kjhughes
  • 106,133
  • 27
  • 181
  • 240
  • 2
    Don't tell us something isn't working. Tell us exactly what you did and exactly how it failed. – Michael Kay Apr 04 '16 at 17:57
  • @KailashSingh: That covers what you did partially -- doesn't include the XML so we can reproduce -- but it doesn't cover how it failed. Worse, your comment added to your question states *this xpath code is working fine for me*, leaving us to wonder what remains of your problem. – kjhughes Apr 04 '16 at 20:22
  • That comment was for @jens Erat working fine means I don't bother about 3.0 or anything else..... It is giving result even if it doesn't fit his definition of 3.0. Now I am trying to make my search case insensitive..... – Kailash Singh Apr 04 '16 at 20:42