这个JSON对XSS安全吗?

Hello I have been creating a sort function for a bunch of divs. For it to work I use the data atrribute of each div. To get the attributes into the div I have been using a javascript loop. I get the data from a php page where I have used json_encode to return the data in the variable 'peoplelist' It looks like below (although could have 1000 records). I have stripped all characters except A-z and numbers and replaced them with _ (this is for the sorting system to work properly)

[{
    "idnum": "100899801298",
    "firstname": "Lola",
    "surname": "Richards ",
    "sortcat1": "possibly bad infor",
    "sortcat2": "possibly bad data"
}, {
    "idnum": "102697973926",
    "firstname": "Lola",
    "surname": "Simonson",
    "sortcat1": "possibly bad infor",
    "sortcat2": "possibly bad data"
}, {
    "idnum": "154845984715",
    "firstname": "Simon",
    "surname": "Jones",
    "sortcat1": "possibly bad infor",
    "sortcat2": "possibly bad data"
}]

I had read that creating a variable and adding all the html to my div called "putdatahere" is more efficient(see below) however after reading a lot it seems this is open to XSS.

$.ajax({
type: "post",
url: "getdata.php",
cache: false,
success: function(peoplelist) {
    var peopleinfo = JSON.parse(peoplelist);
    var i,x="";
    for (i in peopleinfo) {
        var idnumstringed = pupilinfo[i].idnum.replace(/[^a-zA-Z0-9]/g, '_');
        var firstnamestringed = pupilinfo[i].firstname.replace(/[^a-zA-Z0-9]/g, '_');
        var surnamestringed = pupilinfo[i].surname.replace(/[^a-zA-Z0-9]/g, '_');
        var sortcat1stringed = pupilinfo[i].sortcat1.replace(/[^a-zA-Z0-9]/g, '_');
        var sortcat2stringed = pupilinfo[i].sortcat2.replace(/[^a-zA-Z0-9]/g, '_');
        var sortcat3stringed = pupilinfo[i].sortcat3.replace(/[^a-zA-Z0-9]/g, '_');
        var x+='<div id="pupdiv'+idnumstringed+'" data-firstname="'+firstnamestringed+'" data-surname="'+surnamestringed+'"  data-sortcat="'+sortcat1stringed+'" data-sortcat2="'+sortcat2stringed+'">'+firstname+' '+surname+'</div>';
    }
   $("#putdatahere").html(x);
   }
});

I had read that the only safe way to use unknown data is to put it in .text instead of .html. I don't know how to do this with the above method so I have now appended each div as we go along (see below)

 $.ajax({
type: "post",
url: "getdata.php",
cache: false,
success: function(peoplelist) {
    var peopleinfo = JSON.parse(peoplelist);
    var i,x="";
    for (i in peopleinfo) {
        var idnumstringed = pupilinfo[i].idnum.replace(/[^a-zA-Z0-9]/g, '_');
        var firstnamestringed = pupilinfo[i].firstname.replace(/[^a-zA-Z0-9]/g, '_');
        var surnamestringed = pupilinfo[i].surname.replace(/[^a-zA-Z0-9]/g, '_');
        var sortcat1stringed = pupilinfo[i].sortcat1.replace(/[^a-zA-Z0-9]/g, '_');
        var sortcat2stringed = pupilinfo[i].sortcat2.replace(/[^a-zA-Z0-9]/g, '_');
        var sortcat3stringed = pupilinfo[i].sortcat3.replace(/[^a-zA-Z0-9]/g, '_');         
        $("#putdatahere").append('<div id="pupdiv'+idnumstringed+'" data-firstname="'+firstnamestringed+'" data-surname="'+surnamestringed+'"  data-sortcat="'+sortcat1stringed+'" data-sortcat2="'+sortcat2stringed+'"></div>');
        $("#pupdiv"+idnumstringed).text(firstname+' '+surname);     
    }
}
}); 

My questions are:

1) is the above append method safe from XSS or other attacks?

2) is there a better way to do this?

Removing all the non-alphanumeric characters should make it safe. But a better way is to create the element using jQuery's functional method rather than concatenating strings.

$("#putdatahere").append($("<div>", {
    id: "pupdiv" + idnum,
    data: { 
        firstname: pupilinfo[i].firstname,
        surname: pupilinfo[i].surname,
        sortcat: pupilinfo[i].sortcat1,
        sortcat2: pupilinfo[i].sortcat2,
        sortcat3: pupilinfo[i].sortcat3
    },
    text: pupilinfo[i].firstname + " " + pupilinfo[i].surname
}));

BTW, you forgot to put sortcat3 in the element, and you left off pupilinfo[i]. when calling .text().