Those pesky quotation marks

May 29, 2013 at 12:00 PM
For a directory, I'm attempting to retrieve names and data beginning with their email address. Two addresses--both with single quotes--elude me. I've tried everything I can think of, but nothing has worked. Any ideas?
        ...
        var arFolks = ["O'KeeffePM@some.org", "O'DonoghueDW@some.org"];
        ...
        for(var l=0; l<arFolks.length; l++) {
            strUser = arFolks[l];
            getLoginFromEmail(strUser);
        }
        ...
        function getLoginFromEmail(email) {
//          var whatever = email.replace(/'/g,"\'");    //nothing tried here has helped
            ...
            var promiseEmail = $().SPServices({
                operation: "GetUserLoginFromEmail",
                emailXml: "<Users><User Email=" + email + " /></Users>" 
            });
            promiseEmail.done(function() {
                ...
            });
            promiseEmail.fail(function() {
                alert("Whoops! Failed to retrieve logon from email: " + email);
            });
        }
May 30, 2013 at 12:34 AM
I think you new to XML encode it because the apostrophe is being passed to the server in a SOAP message. Have you tried that?
So a ' will become '


_____
Paul

Sent from mobile device.
May 30, 2013 at 12:49 PM
If you meant replace ' with &apos; , I just tried that: O&O&apos;KeeffePM@some.org but it made no difference.
[I don't know where the extra O comes from in that example, but it should read: O &apos;Kee..., without the space after the O]
May 30, 2013 at 12:56 PM
However, hard-coding the search term (ie, the email address passed in the SOAP) with &apos; for the apostrophe DID the trick. Thanks. I'll now figure out how to make that dynamic...
May 30, 2013 at 6:04 PM
Ok... Good... you definitely need to encode XML characters... You example looks funny to me... You said you changed it to : [email removed] , but that has 1 too many "&O" ?????
Anyway... good luck... glad this worked out.


_________
Paul T

May 31, 2013 at 12:32 PM
One last problem. I had ignored it as "not understandable," but then I think I discovered the problem but certainly not a solution.

My list of email addresses included a perfectly valid one that always fails to be found. Eventually, I added an .always() clause to see what the system was seeing that it resolved as "failure." There in the DisplayName attribute is:
DisplayName="Sxxx, Sxxx "Monti""

My guess is that the use of quotation marks within the quotation marks so confuses the retrieval system that it throws the whole record out. I only want the Login attribute, but nothing is available from this record at any time. I've looked at it to find a place to either suppress DisplayName or otherwise recover some of the data, but can't see anything.

Shall I write this record off as unusable?
May 31, 2013 at 1:00 PM
I stared at what I had written for a bit, then realized, "Well, I've got the responseText, right?" So I eventually came up with this.

I had really liked my .final() clause, because it seemed to identify people for whom I had an email address but who are no longer in the system, so I didn't want to lose that warning, but I want to show user detail for any user who IS in the system. This seems to work:
            promiseEmail.fail(function() {
                hold = promiseEmail.responseText;
                var iIndex = hold.indexOf("Login=");
                if(iIndex == -1) alert("Whoops! Failed to retrieve logon from email: " + email);
                else {
                    var iEnd = hold.indexOf('"', iIndex+7);
                    var login = hold.substring(iIndex+7, iEnd);
                    get_user_profile_by_login(login)
                }
            });
May 31, 2013 at 1:42 PM
I guess I'm not following... could you post the xml returned from Sharepoint call to the GetUserLoginFromEmail operation?

The quotes should be returned encoded, so you should be able to use the value if it is returned.
May 31, 2013 at 2:16 PM
Here's the core routine:
var promiseEmail = $().SPServices({
    operation: "GetUserLoginFromEmail",
    emailXml: "<Users><User Email='" + whatever + "' /></Users>"
});
promiseEmail.done(function() {
    hold = $(promiseEmail.responseXML).SPFilterNode("User").attr("Login");
    get_user_profile_by_login(hold);
});
promiseEmail.fail(function() {
    hold = promiseEmail.responseText;
    var iIndex = hold.indexOf("Login=");
    if(iIndex == -1) alert("Whoops! Failed to retrieve logon from email: " + email);
    else {
        var iEnd = hold.indexOf('"', iIndex+7);
        var login = hold.substring(iIndex+7, iEnd);
        get_user_profile_by_login(login)
    }
});
The done() clause never happens but from fail() I get this:
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><GetUserLoginFromEmailResponse xmlns="http://schemas.microsoft.com/sharepoint/soap/directory/"><GetUserLoginFromEmailResult><GetUserLoginFromEmail><User Login="WASHDC\singlas" Email="SinglaS@some.org" DisplayName="Sxxx, Sxxx "Monti"" SiteUser="0"></User></GetUserLoginFromEmail></GetUserLoginFromEmailResult></GetUserLoginFromEmailResponse></soap:Body></soap:Envelope>
May 31, 2013 at 4:44 PM
Thanks Mike for posting... this is very strange to me and I know realize that I guess it is possible for SharePoint to return invalid SOAP messages... those quotes should have been encoded.
It sounds like you have found a way around it, although not idea... Good luck.