Laboratorium XML
wtorek 11.00—12.30
»Home
»Materiały
  »DTD & co.
  »SAX
  »DOM
  »Zadanie 2
  »XPath
  »XSLT
  »Simple
  »JDOM
  »JS
»Odnośniki
  »Xerces2
»Zadania

XML w JavaScript

Inne linki

Przykładowe użycie XMLHttpRequest (klient gry w pary)

Plik play_js/play.js:

ns = 'http:/example.com/play';
xns = "http://www.w3.org/1999/xhtml";


function uncover(num)
{
    var r = new XMLHttpRequest();
    r.onreadystatechange = function() {
        if (r.readyState == 3) {
            document.getElementById('headers').firstChild.nodeValue =
                r.getAllResponseHeaders();
        } else if (r.readyState == 4) {
            document.getElementById('response').firstChild.nodeValue =
                r.responseText;
            var changes = r.responseXML.getElementsByTagNameNS(ns, 'change');
            for (var i = 0; i < changes.length; i++) {
                var change = changes.item(i);
                var td =
                    document.getElementById('f' + change.getAttribute('num'));
                td.setAttribute('class',
                                'color' + change.getAttribute('color'));
            }
        }
    }
    r.open('post', '/process', true);
    var doc = document.implementation.createDocument(ns, "uncover", null);
    doc.firstChild.setAttribute('num', num);
    r.send(doc);
}

function create_board(n, m)
{
     old = document.getElementById('board');
     table = document.createElement('table', xns);
     table.setAttribute('id', 'board');
     k = 0;
     for (i = 0; i < n; i++) {
         tr = document.createElement('tr', xns);
         for (j = 0; j < m; j++) {
             td = document.createElement('td', xns);
             td.setAttribute('class', "color0");
             td.setAttribute('id', 'f' + k);
             td.setAttribute('onclick', "javascript:uncover(" + k + ")");
             tr.appendChild(td);
             k += 1;
         }
         table.appendChild(tr);
     }
     old.parentNode.replaceChild(table, old);
}


function start(n, m)
{
    var r = new XMLHttpRequest();
    r.onreadystatechange = function() {
        if (r.readyState == 3) {
            document.getElementById('headers').firstChild.nodeValue =
                r.getAllResponseHeaders();
        } else if (r.readyState == 4) {
            document.getElementById('response').firstChild.nodeValue =
                r.responseText;
            create_board(n, m);
        }
    }
    r.open('post', '/process', true);
    var doc = document.implementation.createDocument(ns, "start", null);
    doc.firstChild.setAttribute('size', n * m);
    r.send(doc);
}


function main()
{
    start(4, 4);
}

Plik play_js/index.html:

<!DOCTYPE html
     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <script src="play.js" type="application/x-javascript"/>
    <link rel="stylesheet" type="text/css" href="play.css" />
  </head>
  <body onload="main()">
    <p>
      <a href="javascript:start(4, 4)">4x4</a> ||
      <a href="javascript:start(4, 5)">4x5</a> ||
      <a href="javascript:start(4, 6)">4x6</a>
    </p>
    <table id="board"></table>
    <pre id="request"> </pre>
    <pre id="headers"> </pre>
    <pre id="response"> </pre>
  </body>
</html>

Plik play_js/play.css:

body { background: #8b7e66; /* wheat4 */ }

#board td { width: 50px; height: 50px; }

#board .color0 { background: black }
#board .color1 { background: #cd0000 /* red3 */ }
#board .color2 { background: #0000cd /* blue3 */ }
#board .color3 { background: #cdcd00 /* yellow3 */ }
#board .color4 { background: #00cd00 /* green3 */ }
#board .color5 { background: #008b8b /* cyan4 */ }
#board .color6 { background: #7d26cd /* purple3 */ }
#board .color7 { background: #bc8f8f /* RosyBrown */ }
#board .color8 { background: #cd00cd /* magenta3 */ }
#board .color9 { background: #8b4513 /* SaddleBrown */ }
#board .color10 { background: #bdb76b /* DarkKhaki */ }
#board .color11 { background: #b8860b /* DarkGoldenrod */ }
#board .color12 { background: #a2cd5a /* DarkOliveGreen3 */ }

Przykładowe użycie komunikacji XML (server gry w pary)

import web
import random
import sys

from lxml import etree


ns = 'http:/example.com/play'

urls = (
    '/', 'static',
    '/(play.js|index.html|play.css)', 'static',
    '/process', 'process',
    )


# poor man sessions
sessions = {}


class static:
    def GET(self, name='index.html'):
        print file(name).read()


class Game:

    def __init__(self, n):
        pos = range(n)
        self.left = range(n)
        self.colors = {}
        for i in range(n):
            color = i // 2 + 1
            p = random.choice(pos)
            self.colors[p] = color
            pos.remove(p)
        self.uncovered = []

    def uncover(self, n):
        if n in self.uncovered or n not in self.left:
            return []
        if len(self.uncovered) < 2:
            self.uncovered.append(n)
            return [(n, self.colors[n])]
        else:
            if self.colors[self.uncovered[0]] == self.colors[self.uncovered[1]]:
                self.left.remove(self.uncovered[0])
                self.left.remove(self.uncovered[1])
                result = []
            else:
                result = [(i, 0) for i in self.uncovered]
            self.uncovered = [n]
            result.append((n, self.colors[n]))
            return result


class process:

    def POST(self):
        t = etree.XML(web.data())
        size = t.xpath(u"//p:start/@size", {'p': ns})
        web.header('Content-Type', 'text/xml')
        if size:
            size = int(size[0])
            if size > 100:
                return web.badrequest()
            game = Game(size)
            sid = str(id(game))
            web.setcookie('session_id', sid)
            sessions[sid] = game
            print '<response size="%d"/>' % size
            return
        num = t.xpath(u"//p:uncover/@num", {'p': ns})
        if num:
            field_num = int(num[0])
            try:
                game = sessions[web.cookies('session_id')['session_id']]
            except KeyError:
                return web.badrequest()
            resp = etree.Element('{%s}response' % ns, nsmap={None:ns})
            for num, color in game.uncover(field_num):
                etree.SubElement(resp, 'change', num=str(num), color=str(color))
            etree.ElementTree(resp).write(sys.stdout)
            return
        return web.badrequest()


if __name__ == '__main__':
    web.internalerror = web.debugerror
    web.run(urls, web.reloader)