Glen Robson
Glen Robson

Reputation: 938

Saving a Multidimensional Array into an XML using JavaScript

So I have a multidimensional array that looks like this:

var map = [[0, 0, 0, 0, 0, 0, 0],
           [0, 3, 0, 0, 2, 0, 0],
           [0, 0, 0, 0, 4, 0, 4],
           [0, 0, 0, 0, 5, 0, 5],
           [0, 0, 0, 0, 0, 0, 1],
           [0, 0, 2, 5, 0, 0, 0],
           [0, 0, 0, 2, 0, 0, 0],
           [0, 4, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0]];

And i would like to save it into my XML file.

My XML file looks like the following:

<TileMaps>
<Level> <!-- Level 1  -->
<map>[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
          [1, 3, 2, 4, 0, 0, 0, 0, 0, 1],
          [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]</map>
</Level>
<Level> <!-- Level 2  -->
<map>[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
          [1, 3, 2, 4, 0, 0, 0, 0, 0, 1],
          [1, 0, 2, 4, 0, 0, 0, 0, 0, 1],
          [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]</map>
</Level>
</TileMaps>

So when i add the array i would like it to be placed within the XML file within the:

<Level><map> ARRAY HERE </map></Level>

Thanks

Upvotes: 1

Views: 7266

Answers (3)

Robot Woods
Robot Woods

Reputation: 5687

Here's my solution, it uses PHP in the backend, and JSON, so you'll want to modify your server side code as appropriate (if you wrap the JSON in XML, you'll also need to adjust the syntax in the AJAX pieces)...oh, depending on your target user, you'll want to add some validation to the inputs (both client and server side):

PAGE:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Maker</title>
<style>
#can{width:300px; height:90px; display:block; background-color:#666;}
</style>
</head>

<body>
Which level do you want:<input type="text" id="level_request" value="level1"/><button onclick="init()">Go</button>
</body>
<script>
function saveLevel(){
ajax=((window.XMLHttpRequest)?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP"));
name=document.getElementById('level_name').value; //this grabs the content in the Level Name field
if(name.length>0){
    ajax.onreadystatechange=function()
    {
        if (ajax.readyState==4&&ajax.status==200){
            alert('Level saved');
        }
    }
    params='level='+name+'&map='+JSON.stringify(map); //this constructs the message to send, consisting of the name and map
    ajax.open("POST","levels.php",true); //this is the file you will be POSTing a message to
    ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    ajax.setRequestHeader("Content-length", params.length);
    ajax.setRequestHeader("Connection", "close");
    ajax.send(params);
    }
}

var blocksize=30;
var map=[[1,1,1,1,1,1,1,1,1,1],[1,3,0,0,0,0,2,4,0,1],[1,1,1,1,1,1,1,1,1,1]];
var can;
var ctx;

function init(){
    ajax=((window.XMLHttpRequest)?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP"));
    ajax.onreadystatechange=function()
    {
        if (ajax.readyState==4){ //this test whether the request is complete
            l=document.getElementById('level_request').value;
            document.body.innerHTML='Level Name:<input type="text" id="level_name" /><br/><canvas id="can" width="300" height="90"></canvas><br/><button onclick="saveLevel()">Save</button>'; //this replaces the initial form
            can=document.getElementById('can')
            if(can){ctx=can.getContext('2d');}

            if(ajax.status==200){ //this test whether it was successful
                m=JSON.parse(ajax.responseText);//this overwrites the existing map with the received data
                console.log(m);
                map=m.tilemaps[l];
                for(y=0;y<map.length;y++){
                    for(x=0;x<map[y].length;x++){
                        draw(y,x);
                    }
                }
                can.addEventListener('click',builder);
            }
            else{ //this is what we do if the request is done and it was a failure
                for(y=0;y<map.length;y++){
                    for(x=0;x<map[y].length;x++){
                        draw(y,x);
                    }
                }
                can.addEventListener('click',builder);
                alert('Something went wrong, loading default level');
            }

        }
    }
    ajax.open("GET","levels.php?level="+document.getElementById('level_request').value,true);
    ajax.send();

}

function builder(e){
    if (e == null) {e = window.event;}
    x = e.clientX; //where the click was
    y = e.clientY;
    offsetX = ExtractNumber(can.offsetLeft);//where the canvas is
    offsetY = ExtractNumber(can.offsetTop);
    x_grid=Math.floor((x-offsetX)/blocksize); //which block in the canvas was clicked
    y_grid=Math.floor((y-offsetY)/blocksize);
    map[y_grid][x_grid]++;
    if(map[y_grid][x_grid]>4){map[y_grid][x_grid]=0;}
    draw(y_grid,x_grid);
}

function draw(y,x){
    kind=map[y][x];
    switch(kind){
        case 0:
            ctx.drawImage(floorimg,x*blocksize,y*blocksize);
        break;
        case 1:
            ctx.drawImage(wallimg,x*blocksize,y*blocksize);
        break;
        case 2:
            ctx.drawImage(blockimg,x*blocksize,y*blocksize);
        break;
        case 3:
            ctx.drawImage(playerimg,x*blocksize,y*blocksize);
        break;
        case 4:
            ctx.drawImage(goalimg,x*blocksize,y*blocksize);
        break;
    }
}

function ExtractNumber(value){
    var n = parseInt(value);
    return n == null || isNaN(n) ? 0 : n;
}
var floorimg=new Image();
floorimg.src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAE5JREFUeNpiNDU1ZaANYAHiadOmEaM0KysLSOaCSYJg8rRpTAw0A6NGjxo9avQIMJqRdiUfDV3NQlI5SVIJPJpCRo0eNXrU6EFaqAIEGABIow4bXRyDLQAAAABJRU5ErkJggg==';
var wallimg=new Image();
wallimg.src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEFJREFUeNpirK+vZ8AGGhsbcUkRqYaJgWZg1Gj6AUZIFFOeHjDVjEbjcEoho2XIaAoZLUNGU8hoGTKaQmgAAAIMAJeMK58/yjg2AAAAAElFTkSuQmCC';
var blockimg=new Image();
blockimg.src='data:image/png;base64,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';
var playerimg=new Image();
playerimg.src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAATdJREFUeNpiNDU1ZaANYAHiadOm4ZLGZfGi+fPxmzt52jQWPNJAc/8rKSGLMN679//+ThBD0Z2g6UwMNAM0NJqFVA3AoCAmrAkbDQxcUiOQgNGQhGHc+QpTKi5RjMgEw4LVXKyGQgBE6my5GFwNkF1VW9vc0MDMzIwvGvGbi2wB0EQ4+8mTJ4kpKTRJIRDXFJWU4DSaSCdjOhzCffP2bVxiIk3SNZqzaJxlsrKyqGjiZFhhR2NX58JcjRwJZANIEQ0MiSFS8iGnRXSjgUUBmjR+g5BTG0Tj6dOnqexqiLknTpzAFyBEOhyteAKSJ0+eRCueWLCWkJCSE2umh1uM7ALkcCBQXkPKX6xFM1ZTyKllMGt0SC1BjAUk142wxoIpQdOHX2MBGJmMGKUKpLFATFgz0q45CRBgAHQ6gQd/qFgwAAAAAElFTkSuQmCC';
var goalimg=new Image();
goalimg.src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAFtJREFUeNpilJSUZKANYAFiGRkZqpv75MkTJgaagWFv9BMwGA2QUaNHttEsmPmCYMbBJYVWzNHR1XgKWIh7iS+BR1PIqNEjIaPjAaQ2V0bDGktYk9S6IB4ABBgADi4U6URvDncAAAAASUVORK5CYII=';
</script>
</html>

levels.php:

<?php
if($_REQUEST['level']&&$_REQUEST['map']){
    $file=file_get_contents('levels.txt'); //get the existing content
    $json=json_decode($file); //convert it from string to object
    $tilemaps=$json->tilemaps;
    $tilemaps->$_REQUEST['level']=json_decode($_REQUEST['map']);
    $o['tilemaps']=$tilemaps;
    $str=json_encode($o);
    $pos=fopen('levels.txt','w');
    fwrite($pos,$str);
    fclose($pos);
}
else{
    header('content-type:application/json');
    echo file_get_contents('levels.txt');
}
?>

Upvotes: 0

Diode
Diode

Reputation: 25135

Using JSON is recommended for this. Anyway, giving a solution if you want to proceed with XML.

Array to XML

Build XML string using string concatenation. Use Crockford's JSON library for building the array string.

var map = [[0, 0, 0, 0, 0, 0, 0],
           [0, 3, 0, 0, 2, 0, 0],
           [0, 0, 0, 0, 4, 0, 4],
           [0, 0, 0, 0, 5, 0, 5],
           [0, 0, 0, 0, 0, 0, 1],
           [0, 0, 2, 5, 0, 0, 0],
           [0, 0, 0, 2, 0, 0, 0],
           [0, 4, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0]];

var xml = '<TileMaps><level><map>';
xml += JSON.stringify(map);
xml  += '</map></level></TileMaps>';

alert(xml);

jsfiddle : http://jsfiddle.net/diode/ZfWjp/

Then send it to server side for saving.

XML to Array

Load saved XML from server.

Use jQuery to parse it.

var xml = '<TileMaps><level><map>[[0,0,0,0,0,0,0],[0,3,0,0,2,0,0],[0,0,0,0,4,0,4],[0,0,0,0,5,0,5],[0,0,0,0,0,0,1],[0,0,2,5,0,0,0],[0,0,0,2,0,0,0],[0,4,0,0,0,0,0],[0,0,0,0,0,0,0]]</map></level></TileMaps>';

var map = $.parseJSON($(xml).find("map").text());

alert(map[0]);
alert(map[1]);

jsfiddle : http://jsfiddle.net/kBrCT/1/

note : You have to modify this if there are multiple map nodes in single XML file.

Upvotes: 2

Ben
Ben

Reputation: 21249

Well if it's just the transformation of the array itself to string you could do this:

var data = [[0, 0, 0, 0, 0, 0, 0],
       [0, 3, 0, 0, 2, 0, 0],
       [0, 0, 0, 0, 4, 0, 4],
       [0, 0, 0, 0, 5, 0, 5],
       [0, 0, 0, 0, 0, 0, 1],
       [0, 0, 2, 5, 0, 0, 0],
       [0, 0, 0, 2, 0, 0, 0],
       [0, 4, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0]];


var dataAsString = "[" + data.map(function(item){return "["+item.toString()+"]"}).toString() + "]"

console.log(dataAsString);

Note: map is a recent enough addition to Javascript, it may not work in every browser (c.f. Mozilla Docs)

Upvotes: 0

Related Questions