Validating XCRI-CAP using Schematron

January 7th, 2010 by dms2ect

Here I hope to give a quick start on how to use Schematron with your XCRI-CAP documents to give useful feedback.

The instructions here were originally tested on OS X but should also work on Windows or your Linux disto of choice providing you have Java. If there are any differences I am not aware of please leave a comment.

Setting up your environment

You will need:

• ISO Schematron
• A Schematron Schema
• An XLST processer
• An XCRI-CAP document for validation.

ISO Schematron
We’ll be using ISO Schematron, which is available for download from the schematron website: The file we want is iso-schematron-xslt2.zip, I recommend unzipping it to your desktop and renaming it schematron. Place the XCRI-CAP document you wish to validate into this directory.

Processor
The schematron schema is transformed into a XLST stylesheet using a XLST processor; in this example I am going to use Saxon-B for Java, which is an open source XSLT processor.

Once downloaded you will need to add saxon.jar to your classpath. On OS X 10.5+ you can place it into your /Library/extensions/Java directory.

Schematron Schema
A Schematron schema is needed validate against your XCRI-CAP XML document. The schema takes the form of xpath expressions; I have written one based on XCRI-CAP 1.1 which you can download here; feel free to use and modify. Once downloaded place into your schematron directory. You will also need this list of postcodes.
Now you should now have a directory named schematron with multiple files; it is important that you have the following five:

• iso_svrl_for_xlst2.xsl
• iso_schematron_skeleton_for_saxon.xsl
• xcri.iso.sch
• postcodes.xml
• your own XCRI-CAP document!

Validating your XCRI-CAP documents

First we need to create an xsl stylesheet which will be used as the validation engine against our XCRI-CAP document.
Open a terminal/prompt navigate to your schematron directory and issue the following command:

java net.sf.saxon.Transform -o xcri.iso.sch.tmp.xsl -s xcri.iso.sch iso_svrl_for_xslt2.xsl

This will use the Saxon processor we installed earlier to compile the schema into an XLST stylesheet (xcri.iso.sch.tmp.xsl) using our schema, Schematron xsl and the Saxon processor. The next step is to use the file we have created against our XCRI-CAP document to create an error report. To do this run the following changing ‘myfile.xml’ to the name of your document:

java net.sf.saxon.Transform -o errors.report.xml -s myfile.xml xcri.iso.sch.tmp.xsl

You should now have an error report called errors.report.xml. The report is in SVRL format which is a simple language defined in ISO schematon. SVRL can be used as the basis for further transformations and to demonstrate this I have written a small xsl which you can use to transform this into an HTML document. If you wish to do so, download to your schematron directory, make any modifications you require and use the following:

java net.sf.saxon.Transform -o errors.html errors.report.xml svrl_transformer.xsl

You should now have the HTML document of errors in your schematron directory errors.html

Line Numers
You should now be producing feedback on your XCRI-CAP documents and producing a simple html document of errors. If you are using a version of Saxon that allows access to its extensions then you we can use the saxon:line-number() extension to report line numbers.

To do so replace these files in your schematron directory with these modified versions:

iso_svrl_for_xslt2.xsl

iso_schematron_skeleton_for_saxon.xsl

And run though the validation steps again with the -l flag set. eg:

java net.sf.saxon.Transform -l -o xcri.iso.sch.tmp.xsl -s xcri.iso.sch iso_svrl_for_xslt2.xsl

java net.sf.saxon.Transform -l -o errors.report.xml -s myfile.xml xcri.iso.sch.tmp.xsl

java net.sf.saxon.Transform -l -o errors.html errors.report.xml svrl_transformer.xsl

Don’t have time to give it a go? You can use the our ‘beta’ web based validator that will validate your XCRI-CAP document using the same steps shown in this post. You can find the validator a:

http://galadriel.cetis.ac.uk/XCRIValidator/

Comments very welcome!

The Evolution of Digital Distribution Systems in Gaming

March 30th, 2009 by dms2ect

Digital distribution is everywhere; applications such as iTunes provide the ability for digital products such as MP3s, movies and computer software to be delivered to audiences over the Internet instead of using physical media such as CDs, DVDs or Blu Ray. They provides easy and direct sales to a global market. With iTunes and the App Store ‘Apple’ may be the company that comes to mind when digital distribution is discussed but it shouldn’t be forgotten that plenty of video game consumers have been using these systems for years and recent announcement at this years Game Developer Conference 2009 have really shown that there are plenty more exciting developments to come.

Over the past 5 years gaming has seen a massive rise in digital distribution systems; many customers have been more then willing to make the switch from obtaining a physical copy of computer game software from a ‘bricks and mortar’ shop to downloading it through through distribution systems such as Steam, Impulse, Xbox Live Arcade and PSN. Some of the advantages distribution systems have over their convention counterpart include:

  • Instant user feedback
  • Anti-cheating Systems for online games
  • Auto patching
  • Downloading purchased-content from any location

For myself the big draw was (and still is!) the last bullet point. The idea that once I bought a game I could download it as many times as I wanted; even if I buy my product from a ‘real’ shop, the first thing I do is enter the serial code into a system as a backup, just in case it gets lost/snapped/broken.

Since I started using such systems when Steam first launched in 2003 there have always been two questions for me. The first is is how long will be before we no longer need to download the game? When can we stop buying into the expensive CPUs,GPUs and PPUs that games require and let all the processing be done server side? A recent announcement this week and ongoing work by Valve suggest it might be closer then we think.

The second was how digital distribution systems could move into different markets. In the UK most gamers will have broadband connections and a 7th generation console(or PC) since we are constantly after that new game and are a easy target for publishers; but what about markets that don’t buy into the latest consoles and games? Brazil has a massive gaming market, but one quite different from the situation in the UK with older consoles such as the Master System still seeing re-releases as late as 2006. Another exciting announcement at GDC 2009 saw a console designed exactly for such markets, pushing digital distribution as its method of obtaining games sales.

Moving into the Cloud

LiveOne

This week at the Game Developer Conference 2009 it was announced that LiveOne is a game distribution system that promises to take the load away from your computer and onto the cloud; allowing resource hungry games to play on modest hardware.The LiveOne developers maintain that the main bottleneck is bandwidth, with lower bandwidth users simply being met with a smaller screen resolution. This is really exciting news for gamers; does it mean it mean that digital distribution and cloud computing will kill the console/PC spec war, will we no longer go through generation after generation of video game consoles?

Steam Cloud

Although it would seem that Valve don’t think we are ready for such a radical shift they are still moving in a similar direction with their product ‘Steam Cloud’. Although Steam Cloud still delivers the game to the end user via a full download the idea is that variable data such as save games and settings are stored in the cloud meaning users can log on from any terminal with the game installed and carry on from where they left off.

Expanding the Market

Tectoy announced they would be attempting to push digital distribution into ‘The Next Billion’ Market by creating a console that will sell and distribute games through 3G or Edge networks using a virtual currency not unlike Microsoft or Wii Points. The seems to be no shortage of publishers wanting their games on the system; and a quick scan of the games that will be available (Crash Nitro Kart, Quake, Sonic Adventure to name a few) would make it seem that these publishers are egar to bring their old games to new markets; with digital distribution being the ideal means to do so. I find it fascinating that the company have decided that a decided to enter these markets via the digital distribution route.

Where next?

It is no secret that there is a huge amount of money in games and this is the driving force behind these incredible innovations. As always though the technology will filter down and hopefully we will see the technology in other areas. Could application processing in the cloud mean we see an end to the PC CPU/GPU spec wars forcing PC manufacturers to focus their initiative in others areas? Will it mean that high-end programs will be able to run on your mobile phone with a small client purchase simply being made over 3G/Wimax etc? I’m sure there are plenty of exciting discussions to be had at future CETIS Cloud Computing and Institutions Working Group meetings!

Widgets for Wookie: Getting Started

August 18th, 2008 by dms2ect

Please note the widget tutorials are very much a work in progress.

The Wookie server is open source software in development for delivering collaborative widgets that follows the w3c widget specification. Although it is early days for Wookie I desperately wanted to try my hand at writing some widgets; along the way I found that online tutorials were often written for specific platforms (Yahoo, Mac, etc) and it was quite daunting for the first few attempts.

Getting Started

First you will need download and install the Widget Server.  The easiest method is to use the ‘Quick Start Distribution’ which is offered by the  Tencompetence Website and includes:

  • CopperCore Runtime Environment(CCRT)
  • Sled Player
  • Widget Server

The Quick Start Distribution is available here

Once you have downloaded the environment unzip it with your favorite compression tool and run the file coppercore.bat.  Once the script has finished you should be able to use the following URLS a web browser:

http://localhost:8080/wookie to access the Wookie Widget Server index page

http://localhost:8080/sled3 to access the SLeD player

For this tutorial we are interested in the Wookie Player; you should now be able to access the Wookie index page via http://localhost:8080/wookie

Wookie index page

Creating a Widget

For this example we are going to create a very simple widget that displays a calendar. Hopefully this will familiar ourselves with the way in which we create, upload, initiate and access widgets in Wookie; all we will need for this is any old text editor. The code required to make the calendar is available freely from the JavaScript Source WebsiteFirst we need to create a directory that will contain our widgets files, I have called mine ‘calendar’ and stored it on my desktop. For this simple widget we will need to create four files within this directory:

  1. The Configuration document - To tell the server what to do with our widget
  2. HTML page - The page the user will see
  3. CSS file - A file describing the style of the HTML page
  4. A JavaScript file - To store the code that will make our calendar work.

Configuration Document

The configuration document is an XML file that should be named config.xml and is required by the Wookie server to configure the widget. To create one open up your text editor then copy and paste the following:


<?xml version="1.0" encoding="UTF-8" ?><widget chrome="" 
   height="0" id="http://www.tencompetence.org/calendarWidget"
   start ="calendar.htm" version="9" width="0"
   xmlns="http://http://www.w3.org/ns/widgets"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://http://www.w3.org/ns/widgets w3cwidgets.xsd">
  <title>The calendar widget!</title>
  <description>A sample calendar widget for demonstration purpose</description>
  <author>David Sherlock</author>
</widget>

This contains the bare minimum that is required by the widget server; you should change my name and details and then save the file as config.xml.

HTML file
Since the CSS and Javascript files contain detail on how to the calendar will be created and displayed the HTML file is minimal:

<html>
<head>
 <link rel="stylesheet" href="calendar.css" type="text/css"/>
 <script type='text/javascript' src='calendar.js'> </script>
</head>
<body>
<script type="text/javascript">writeCalendar()</script>
</body>
</html>

This simply specifies the CSS and JavaScript files, this should now be saved within the same directory as our config.xml as calendar.htm.

Javascript and CSS files
Finally we need to create the Javascript and CSS that will create the calendar; this example has been taken from the Javascript Source website.

The CSS should be copied in to a file within our directory called calendar.css:



span.label {
color:black;
width:30;
height:16;
text-align:center;
margin-top:0;
background:#ffF;
font:bold 13px Arial
}

span.c1 {
cursor:hand;
color:black;
width:30;
height:16;
text-align:center;
margin-top:0;
background:#ffF;
font:bold 13px Arial
}

span.c2 {
cursor:hand;
color:red;
width:30;
height:16;
text-align:center;
margin-top:0;
background:#ffF;
font:bold 13px Arial
}

span.c3 {
cursor:hand;
color:#b0b0b0;
width:30;
height:16;
text-align:center;
margin-top:0;
background:#ffF;
font:bold 12px Arial
}

The accompanying JavaScript should also be stored in our working directory within a file called calendar.js. you can get the required JavaScript from here:



function maxDays(mm, yyyy){
var mDay;
if((mm == 3) || (mm == 5) || (mm == 8) || (mm == 10)){
mDay = 30;
}
else{
mDay = 31
if(mm == 1){
if (yyyy/4 - parseInt(yyyy/4) != 0){
mDay = 28
}
else{
mDay = 29
}
}
}
return mDay;
}
function changeBg(id){
if (eval(id).style.backgroundColor != "yellow"){
eval(id).style.backgroundColor = "yellow"
}
else{
eval(id).style.backgroundColor = "#ffffff"
}
}
function writeCalendar(){
var now = new Date
var dd = now.getDate()
var mm = now.getMonth()
var dow = now.getDay()
var yyyy = now.getFullYear()
var arrM = new Array("January","February","March","April","May","June","July","August","September","October","November","December")
var arrY = new Array()
for (ii=0;ii<=4;ii++){
arrY[ii] = yyyy - 2 + ii
}
var arrD = new Array("Sun","Mon","Tue","Wed","Thu","Fri","Sat")

var text = ""
text = "<form name=calForm>"
text += "<table border=1>"
text += "<tr><td>"
text += "<table width=100%><tr>"
text += "<td align=left>"
text += "<select name=selMonth onChange='changeCal()'>"
for (ii=0;ii<=11;ii++){
if (ii==mm){
text += "<option value= " + ii + " Selected>" + arrM[ii] + "</option>"
}
else{
text += "<option value= " + ii + ">" + arrM[ii] + "</option>"
}
}
text += "</select>"
text += "</td>"
text += "<td align=right>"
text += "<select name=selYear onChange='changeCal()'>"
for (ii=0;ii<=4;ii++){
if (ii==2){
text += "<option value= " + arrY[ii] + " Selected>" + arrY[ii] + "</option>"
}
else{
text += "<option value= " + arrY[ii] + ">" + arrY[ii] + "</option>"
}
}
text += "</select>"
text += "</td>"
text += "</tr></table>"
text += "</td></tr>"
text += "<tr><td>"
text += "<table border=1>"
text += "<tr>"
for (ii=0;ii<=6;ii++){
text += "<td align=center><span class=label>" + arrD[ii] + "</span></td>"
}
text += "</tr>"
aa = 0
for (kk=0;kk<=5;kk++){
text += "<tr>"
for (ii=0;ii<=6;ii++){
text += "<td align=center><span id=sp" + aa + " onClick='changeBg(this.id)'>1</span></td>"
aa += 1
}
text += "</tr>"
}
text += "</table>"
text += "</td></tr>"
text += "</table>"
text += "</form>"
document.write(text)
changeCal()
}
function changeCal(){
var now = new Date
var dd = now.getDate()
var mm = now.getMonth()
var dow = now.getDay()
var yyyy = now.getFullYear()
var currM = parseInt(document.calForm.selMonth.value)
var prevM
if (currM!=0){
prevM = currM - 1
}
else{
prevM = 11
}
var currY = parseInt(document.calForm.selYear.value)
var mmyyyy = new Date()
mmyyyy.setFullYear(currY)
mmyyyy.setMonth(currM)
mmyyyy.setDate(1)
var day1 = mmyyyy.getDay()
if (day1 == 0){
day1 = 7
}
var arrN = new Array(41)
var aa
for (ii=0;ii<day1;ii++){
arrN[ii] = maxDays((prevM),currY) - day1 + ii + 1
}
aa = 1
for (ii=day1;ii<=day1+maxDays(currM,currY)-1;ii++){
arrN[ii] = aa
aa += 1
}
aa = 1
for (ii=day1+maxDays(currM,currY);ii<=41;ii++){
arrN[ii] = aa
aa += 1
}
for (ii=0;ii<=41;ii++){
eval("sp"+ii).style.backgroundColor = "#FFFFFF"
}
var dCount = 0
for (ii=0;ii<=41;ii++){
if (((ii<7)&&(arrN[ii]>20))||((ii>27)&&(arrN[ii]<20))){
eval("sp"+ii).innerHTML = arrN[ii]
eval("sp"+ii).className = "c3"
}
else{
eval("sp"+ii).innerHTML = arrN[ii]
if ((dCount==0)||(dCount==6)){
eval("sp"+ii).className = "c2"
}
else{
eval("sp"+ii).className = "c1"
}
if ((arrN[ii]==dd)&&(mm==currM)&&(yyyy==currY)){
eval("sp"+ii).style.backgroundColor="#90EE90"
}
}
dCount += 1
if (dCount>6){
dCount=0
}
}
}

Packing and uploading

Now we should have 4 files within our directory:

  1. config.xml
  2. calendar.js
  3. calendar.css
  4. calendar.htm

For the Wookie server to accept these we have to turn them into a Widget Resource by creating a valid Zip archive out of them. In Windows XP this can be done by selecting all the files, right clicking one and sending it to a Zip archive:

Initializing Widget

Our newly created Widget Resource is now ready to be installed on the Wookie Server. First we must make sure that the environment is running, if it is not already start the coppercore.bat that we downloaded earlier. Once this has run its course navigate a browser to the Wookie Servers index page at http://localhost:8080/wookie. From here we click on the ‘admin’ link (the default username and password is java/java) to get to the administration admin page:

Menu

There are four steps now we must follow to run our widget:

  1. Create a Service for it
  2. Upload the widget
  3. Set the widget as default for our service
  4. Initialize the widget

Creating a Service

First we are going to create a service for our Widget; by clicking ‘add a new service type’.  There are four default services with the server; these are chat, discussion, forum and vote. Our calendar doesn’t fit into any of these services so we will add one ourselves.  Type ‘calendar’ into the box on the right and press add, once the service is added we can press menu to return to the front page.

Uploading Setting Widget as Service Default

From the menu screen click ‘add new widget’, the widget server will then ask for a valid zip file; browse to the zip file we created before and click upload. Once the widget has been uploaded it will ask which services it belongs to, choose calendar and press submit.

Now we have added the widget to our new service type we want to set it as the default widget for that service, return to the administration menu and choose ‘view existing widgets’. You should now see our calendar widget on the list assigned to calendar service type. To set this as the default widget for the calendar service simply click the blue word calendar.

Services

Initializing Widget
Finally we can initialize and use the widget; we no longer need the Wookie administration page so navigate back to the index page at http://localhost:8080/wookie/ and click initiate. The following screen will ask for parameters for the widget you wish to create; here we will change the user ID to any name you wish and the service to the calendar service we created before.

Test Instantiate

Once we click submit the form should return an XML document; for now we are interested in the URL element of this document.

XML data

Copy and paste the URL from your XML document into the Web browser and you should be presented with the widget we created!

Calendar

The Javascript and CSS used to create the calendar are freely avalible here.

Further Reading

http://www.tencompetence.org/ldruntime/

http://javascript.internet.com/time-date/calendar.html

Can you have my attention please?

June 27th, 2008 by dms2ect


Recently I have been writing a browser extension that keeps track of my activities and the web-based resources I use. I found that the data it collected was actually very valuable to me, it created a mini attention profile and by pushing this into various JavaScript libraries I was able to produce pretty graphs that showed a great deal about the way I work.

During the experience I realized it would be advantageous if I could do two things;

  1. Export this information to a service that could make further recommendations on resources that could improve my working habits.
  2. Tap into the many other ‘Silos’ of information I have accumulated (del.icio.ous , last.fm etc) and use this in conjunction with data my tracker has produced.

Looking for solutions to these problems brought me into the world of DataPortability which is an attempt at using various open standards (such as OAuth and APML discussed here by Scott Wilson) to give users the ability to move data between their silos, applications and web services. It is backed by names such as Digg, Google and Facebook.

What was interesting to me was the prospect of moving my attention profile from one place to another; one reason being that I find some places are very good at capturing a snapshot of my attention but then make poor recommendations on where to go next (such as Simpy); moving my attention profile from somewhere that specializes in capturing it to somewhere that generates user content sounds great; could I upload my delicious bookmarks to Digg and get user generated recommendations on resources to use?

A little research into applications and vendors that support DataPortability standards killed my excitement; I found two services I use that would export my attention profile as APML (Digg and Dandelife) but only one closed beta service (Particls) that would do anything with it!

The only example I found of anything interesting that could be done with DataPortability methods was a set of experiments created by employees at Sun which would create an APML file from my Last.fm and make recommendations based on it (something which Last.fm already does very well).

I find it really surprising there hasn’t been more of an interest in DataPortability and attention profiling especially from a business point of view; the amount of times I am asked to fill in a questionnaire would suggest to me that my attention might be actually worth something! So despite the current lack of services and vendors doing anything ˜cool™ where DataPortability is concerned I am still very optimistic some method of moving my attention around will eventually take off, not just because of the big names and buzz surrounding it; or the benefits users will reap but also because of the value my attention profile is worth to people who wish to sell me things.