1

I am trying to build a function that will properly quote/escape an attribute in XPath. I have seen solutions posted in C# here and here, but my implementation in JavaScript results in an error "This expression is not a legal expression"

Here is my function:

function parseXPathAttribute(original){
            let result = null;
            /* If there are no double quotes, wrap in double quotes */
            if(original.indexOf("\"")<0){
                result = "\""+original+"\"";
            }else{
                /* If there are no single quotes, wrap in single quotes */
                if(original.indexOf("'")<0){
                    result = "'"+original+"'";
                }else{ /*Otherwise, we must use concat() */
                    result = original.split("\"")
                    for (let x = 0;x<result.length;x++){
                        result[x] = result[x].replace(/"/g,"\\\"");
                        if (x>0){
                            result[x] = "\\\""+result[x];
                        }
                        result[x] = "\""+result[x]+"\"";
                    }
                    result = result.join();
                    result = "concat("+result+")";
                }

            }

            return result;
        }

Sample failing input:

"'hi'"

Sample failing output:

concat("","\"'hi'","\"")]

I don't understand why it is an illegal expression (given that the double quotes are escaped), so I don't know how to fix the function.

1 Answer 1

4

\ is not an escape character in XPath string literals. (If it was, you could just backslash-escape one of the quotes, and never have to worry about concat!) "\" is a complete string in itself, which is then followed by 'hi..., which doesn't make sense.

So there should be no backslashes in your output, it should look something like:

concat('"', "'hi'", '"')

I suggest:

function xpathStringLiteral(s) {
    if (s.indexOf('"')===-1)
        return '"'+s+'"';
    if (s.indexOf("'")===-1)
        return "'"+s+"'";
    return 'concat("'+s.replace(/"/g, '",\'"\',"')+'")';
}

It's not quite as efficient as it might be (it'll include leading/trailing empty string segments if the first/last character is a double-quote), but that's unlikely to matter.

(Do you really mean let in the above? This is a non-standard Mozilla-only langauge feature; one would typically use var.)

Sign up to request clarification or add additional context in comments.

1 Comment

I am developing a client app using Mozilla's platform. This isn't for a browser. Thanks.

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.