<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-21005140</id><updated>2011-08-01T22:15:02.565+01:00</updated><category term='xquery gift'/><category term='SPARQL DBpedia'/><category term='XQuery SMS'/><category term='XQuery'/><category term='googlechart sparkline'/><category term='MicroSoft Word'/><category term='SPARQL DBpedia Simile'/><category term='web 2.0'/><category term='exist'/><category term='parameterization.'/><category term='SKOS'/><category term='semantic web'/><category term='AJAX AHAH'/><category term='AIS'/><category term='XQuery unit-test'/><category term='xquery exist'/><category term='e-learning'/><title type='text'>The Wallace Line</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>57</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-21005140.post-6936599472754531537</id><published>2009-05-24T17:03:00.003+01:00</published><updated>2009-05-24T18:36:21.239+01:00</updated><title type='text'>Weather Data on the Web</title><content type='html'>In preparation for our cruise up to Scotland this summer, I'm setting up some SMS services so I can get weather reports on board, provided we're in mobile phone range.  This is based on the two-way service rented from Clickatell.  I recently rewrote a PHP/MySQL router which routes MO calls to an application based on the first word of the message, and returns the reply, if any, to the originator.  Much simpler in XQuery because the routing table is now just a simple XML configuration file and the XQuery code is much cleaner. &lt;br /&gt; &lt;br /&gt;So far I've written services to get the UK shipping forecast, the UK inshore waters forecast and the latest weather conditions at weather buoys.  Each has presented different challenges to acquire the raw data, both technical and legal. In the domain of weather information at least we seem a very long way from an integrated, easy to use, web of data.  &lt;br /&gt;&lt;br /&gt;First the &lt;a href="http://www.metoffice.gov.uk/weather/marine/inshore_forecast.html"&gt;inshore waters forecast&lt;/a&gt;. The only publicly available format is this web page. The Met Office does provide a few RSS feeds but none for shipping forecasts. This web page looks technically  promising for analysis even if I'm unsure of the legal status of this act. I'd like to know how the Met Office is funded currently but failed to discover from a Google quick search. I'd like to know the extent to which this is 'Our Data' and despite the Met Office legal notices and Freedom of Information pages, I'm none the wiser really.  I console myself with the fact that I'm only playing with no intention to produce a commercial service in competition with the Met Offices own services.&lt;br /&gt;&lt;br /&gt;The Inshore waters page looks promising, with sections for each area split into meaningful headings.  However on closer inspection the page suffers from that increasingly common bane of the scrapper, a complex mixture of data and JavaScript. The page appearance is the result of JavaScript processing of bland text. Here is the raw forecast for my bit of the coast:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Lands End to St Davids Head including the Bristol Channel&lt;/strong&gt;&lt;br /&gt;&lt;br&gt;&lt;strong&gt;24 hour forecast:&lt;/strong&gt;&lt;br /&gt; Variable 3 or 4.&lt;br /&gt; Slight becoming moderate later in southwest.&lt;br /&gt; Fair.&lt;br /&gt; Moderate or good.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;!-- &lt;strong&gt;Outlook for the following 24 hours:&lt;/strong&gt; --&gt;&lt;br /&gt;&lt;strong&gt;Outlook:&amp;nbsp;&lt;/strong&gt;&lt;br /&gt;Variable 3 or 4, becoming west or northwest 4 or 5, occasionally 6 later.&lt;br /&gt;Slight or moderate.&lt;br /&gt;Thundery rain or showers.&lt;br /&gt;Moderate or good.&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;Well now. Firstly, this is not all the data in the displayed section; the time span and the strong winds warning(if any) are elsewhere in the HTML. The nice sections are not there: instead the four parts of the forecast separated by fullstops - so the last sentence 'Moderate or good' is the Visibility.  Second, the limits of the areas are identified by place identifiers in the maplet, but these do not appear in the text, and only the full area name can be used to identify. Of course, the ardent scraper can cope with this. I've been forced to add my own area ids however to support the SMS interface:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/Met/inshore.xq?areaid=9"&gt;Lands End to St Davids Head&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;But it's horrible, unstable and makes me wonder if this design is a form of obfuscation. I suppose if they wanted to, they could switch randomly between different HTML/JavaScript layers generating the same appearance and then scrappers would be really stuffed - thankfully that seems not be be the case. &lt;br /&gt;&lt;br /&gt;Next stop, the shipping forecast. In this case the forecast text is not on the page at all but in a generated JavaScript file which defines JavaScript arrays and their values. In an way that's simpler because I just have to fetch the JavaScript source and parse it. This application and its design is described in detail in the &lt;a href="http://en.wikibooks.org/wiki/XQuery/UK_shipping_forecast"&gt;XQuery Wikibook&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Over in the States, their freedom of information creates a very different data climate, and NOAA provides a wonderful array of RSS and XML feeds.  However, reusing even this data is not without its problems.  One set of feeds I want to tap into are the data from weather buoys around the world.  Many are operated by NOAA and others by local Met services or commercial operations. The &lt;a href="http://www.ndbc.noaa.gov/maps/United_Kingdom.shtml"&gt;UK coverage&lt;/a&gt; shows the locations and identifiers for UK station and there is an RSS feed of the current conditions at a buoy. The nearest up-weather buoy to Bristol is &lt;a href="http://www.ndbc.noaa.gov/data/latest_obs/62303.rss"&gt;62303, Pembroke Buoy&lt;/a&gt;.  Well this is certainly easily accessible and valid RSS - but ...  all the useful data is CDATA text in the description element:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;strong&gt;May 24, 2009 0700 UTC&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;        &lt;strong&gt;Location:&lt;/strong&gt; 51.603N 5.1W&lt;br /&gt;&lt;br /&gt;        &lt;strong&gt;Wind Direction:&lt;/strong&gt; SE (140&amp;#176;)&lt;br /&gt;&lt;br /&gt;        &lt;strong&gt;Wind Speed:&lt;/strong&gt; 5 knots&lt;br /&gt;&lt;br /&gt;        &lt;strong&gt;Significant Wave Height:&lt;/strong&gt; 3 ft&lt;br /&gt;&lt;br /&gt;        &lt;strong&gt;Atmospheric Pressure:&lt;/strong&gt; 30.14 in (1020.8 mb)&lt;br /&gt;&lt;br /&gt;        &lt;strong&gt;Pressure Tendency:&lt;/strong&gt; +0.03 in (+1.0 mb)&lt;br /&gt;&lt;br /&gt;        &lt;strong&gt;Air Temperature:&lt;/strong&gt; 51&amp;#176;F (10.8&amp;#176;C)&lt;br /&gt;&lt;br /&gt;        &lt;strong&gt;Dew Point:&lt;/strong&gt; 49&amp;#176;F (9.3&amp;#176;C)&lt;br /&gt;&lt;br /&gt;        &lt;strong&gt;Water Temperature:&lt;/strong&gt; 52&amp;#176;F (11.1&amp;#176;C)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So to separate this into meaningful data with semantic markup requires string parsing to extract the data, conversion to standard formats (the date for example)  and markup in some XML Schema. Again XQuery can do the analysis. Here is the &lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/Met/buoy.xq?id=62303"&gt;Pembroke Buoy&lt;/a&gt; current data. The data is augmented with some additional derived data, the wind strength on the Beaufort scale. &lt;br /&gt;&lt;br /&gt;Of course it would be better to use existing XML schemas or RDF vocabularies than invent my own. However there doesn't seem to be anything in use which fits the bill  There is some work on XML schemas for research data interchange but nothing for simple observations and forecasts that I could find.  Perhaps the most comprehensive set of element names on which to build is to be found in the NOAA observation XML feeds such as this for &lt;a href="http://www.weather.gov/xml/current_obs/KNYC.xml"&gt;Central Park, New York&lt;/a&gt;. This is a prime example of how data could be provided and its delightfully simple use makes it a good candidate for student exercises. In this format, both formatted strings and atomic values are provided. In contrast to the use of an attribute for unit, the element name is a concatenation of measurement name and unit, which seems somewhat problematic to me. The data has an attached  &lt;a href="http://www.weather.gov/xml/current_obs/current_observation.xsd"&gt; XML schema&lt;/a&gt; but curiously the data is not valid according to this schema. Instead of omitting missing or undefined values, as the schema requires, the text NA is used instead.  I emailed the office responsible for this data and was informed that they decided to do this because they got too many enquiries about missing data so they added the NA to make it clear it was really missing! There certainly seems to be a genuine problem there for users who don't read the schema, but my follow-up question as to why, in that case, they didn't change the schema went unanswered.&lt;br /&gt;&lt;br /&gt;Weather data represents a case where the domain is generally understood and of interest, large quantities of data are being generated and the data is of critical importance to many users, making it an ideal case study in the web of data for my students. Despite widespread discussion of XML and RDF standards, practical data mashups must rely on hand-coded scrapping, home-build vocabularies and data extracted on dodgy legal grounds. Surely we can do better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-6936599472754531537?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/6936599472754531537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=6936599472754531537&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/6936599472754531537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/6936599472754531537'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2009/05/weather-data-on-web.html' title='Weather Data on the Web'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-6034558301719064905</id><published>2009-05-13T19:56:00.003+01:00</published><updated>2009-05-13T20:16:11.111+01:00</updated><title type='text'>Twitter Radio</title><content type='html'>Thought I'd try to get my XQuery Twitter Radio application going to listen to the tweets from the Mark Logic conference.  It's only a simple script, requires Opera with Voice enabled and uses http-equiv="refresh" to refresh the page.  It only works if the window is active, so it rather limits my use of the computer - just need another to run the radio I guess. If I wasn't marking, I'd write an AJAX-based version. XHTML+Voice is quite tricky to get right however.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/Twitter/twitterRadio.xq?search=%23mluc09&amp;seconds=60&amp;n=6"&gt;Twitter Radio on #mluc09&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I rather like the idea of following the Mark Logic conference with an eXist-based mashup - perhaps we should organise an eXist conference in Bristol - with my part-time status next academic year, perhaps I should put some effort into an event in Bristol.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-6034558301719064905?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/6034558301719064905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=6034558301719064905&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/6034558301719064905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/6034558301719064905'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2009/05/twitter-radio.html' title='Twitter Radio'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-9053493105371338202</id><published>2009-05-06T07:56:00.004+01:00</published><updated>2009-05-06T10:31:09.056+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XQuery'/><category scheme='http://www.blogger.com/atom/ns#' term='exist'/><title type='text'>Matching sequences in XQuery</title><content type='html'>Collation is a core algorithm in processing sequences. In XQuery, the straight-forward expression of the algorithm is as a recursive function:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;declare function local:merge($a, $b  as item()*) &lt;br /&gt;        as item()* {&lt;br /&gt;    if (empty($a) and empty($b))&lt;br /&gt;    then ()&lt;br /&gt;    else if (empty ($b) or $a[1] lt $b[1])&lt;br /&gt;    then  ($a[1], local:merge(subsequence($a, 2), $b))&lt;br /&gt;    else  if (empty($a) or $a[1] gt $b[1])&lt;br /&gt;    then  ($b[1], local:merge($a, subsequence($b,2)))           &lt;br /&gt;    else (: matched :)&lt;br /&gt;             ($a[1], $b[1],  &lt;br /&gt;              local:merge(subsequence($a,2),&lt;br /&gt;              subsequence($b,2)))&lt;br /&gt;   };&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Coincidently, Dan McCreary was writing an article in the&lt;a href="http://en.wikibooks.org/wiki/XQuery/Compare_with_XQuery"&gt; XQuery wikibook&lt;/a&gt; on matching sequences using iteration over one sequence and indexing into the second.  The task is to locate missing items.  Collation is one approach to this task, albeit requiring that the sequences are in order.&lt;br /&gt;&lt;br /&gt;Here is a &lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/UnitTest2/runTests.xql?uri=/db/Wiki/UnitTest2/Tests/collate.xml"&gt;test suite&lt;/a&gt; comparing three methods of sequence comparison. &lt;br /&gt;&lt;br /&gt;I also did some volume tests with two sequences differing by a single, central value.  Here are the &lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/UnitTest2/runTests.xql?uri=/db/Wiki/UnitTest2/Tests/collate2.xml"&gt; tests on a sequence&lt;/a&gt; of 500 items.  In summary, the timings are :&lt;br /&gt;&lt;br /&gt;* Iteration with lookup: &lt;strike&gt;6984 ms&lt;/strike&gt; - not repeatable - average is 2600&lt;br /&gt;* Iteration with qualified expression: 1399 ms&lt;br /&gt;* Recursive collate: 166 ms&lt;br /&gt;&lt;br /&gt;The collate result is surprising and rather impressive. Well done eXist!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-9053493105371338202?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/9053493105371338202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=9053493105371338202&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/9053493105371338202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/9053493105371338202'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2009/05/matching-sequences-in-xquery.html' title='Matching sequences in XQuery'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-7825894116500219895</id><published>2009-05-01T17:10:00.003+01:00</published><updated>2009-05-01T17:28:16.491+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xquery exist'/><title type='text'>More XQuery performance tests</title><content type='html'>I noticed this morning that Dan had added an alternative implementation to an article in the XQuery Wikibook on matching words against a list.  It got me wondering which implementation was preferable.  I wrote a few tests and was surprised at the result. My initial implementation based on element comparisons was five times slower than comparing with a sequence of atoms, and Dan's suggestion of using a qualified expression was worse still.&lt;br /&gt;&lt;br /&gt;Here is &lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/UnitTest2/runTests.xql?uri=/db/Wiki/UnitTest2/Tests/match.xml"&gt;the test run&lt;/a&gt; and the &lt;a href="http://en.wikibooks.org/wiki/XQuery/Filtering_Words"&gt;Wikibook article&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-7825894116500219895?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/7825894116500219895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=7825894116500219895&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/7825894116500219895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/7825894116500219895'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2009/05/more-xquery-performance-tests.html' title='More XQuery performance tests'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-3893961577628741877</id><published>2009-04-27T21:09:00.002+01:00</published><updated>2009-04-28T08:00:32.875+01:00</updated><title type='text'>XQuery Unit Tests</title><content type='html'>I had a fright last week - Wolfgang asked for a copy of the test harness I'd used to evaluate different implementations of a lookup table.  This is code I wrote some time ago, tinkered with, good enough for our internal use but ...  well pretty bad code. &lt;br /&gt;&lt;br /&gt;I have to confess here that as a lone XQuery programmer, my code doesn't get the level of critique it needs.  The Wikibook has been disappointing in that regard: I've published thousands of lines of code there and there has not been a single criticism or improvement posted. Typos in the descriptions are occasionally corrected by helpful souls, graffiti erased by others but as a forum for honing coding skills - forget it.  In my task as project leader on our FOLD project (now coming to an end), I see and review lots of my students' code as well as the code Dan McCreary contributes to the WikiBook so I do quite a bit of reviewing. However I am only too conscious of the lacunae in my XQuery knowledge which perhaps through over kindness or because everyone is so busy, remain for too long. I'm envious of my agile friends who have been pair-programming for years. Perhaps there should be a site to match up lonely programmers for occasional pairing.&lt;br /&gt;&lt;br /&gt;Anyway the test suite got a bit of work on it one day last week and its looking a bit better.   &lt;br /&gt;&lt;br /&gt;Here is a &lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/UnitTest2/Tests/unittests.xml"&gt;sample test script&lt;/a&gt; . As a test script to test the test runner it has the unusual property that some failed tests are good since failing is what's being tested. Here is it &lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/UnitTest2/runTests.xql?uri=/db/Wiki/UnitTest2/Tests/unittests.xml"&gt;running&lt;/a&gt;.&lt;br /&gt;Here is another, used to test &lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/UnitTest2/Tests/lookup.xml"&gt;the lookup implementations&lt;/a&gt; and one to test the&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/UnitTest2/Tests/lookup.xml"&gt; geodesy functions.&lt;/a&gt;  &lt;br /&gt;&lt;br /&gt;Version 1 of the test runner executed tests and generated a report in parallel. A set of  tests may have a common set of modules to import, prefix and suffix code.  For each test, modules are dynamically loaded, the code concatenated and then evaled inside a catch.  &lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;let $extendedCode := concat($test/../prolog,$test/code,$test/../epilog)&lt;br /&gt;let $output :=  util:catch("*",util:eval($extendedCode),&lt;error&gt;Compile error&lt;/error&gt;)        &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The output is compared with a number of expected values.  Comparison may be string-based, element-based, substring present or absent.   (I also need to add numerical comparison with defined tolerance.) A test must meet all expectations to pass. &lt;br /&gt; &lt;br /&gt;To get a summary of the results requires either running the sequence of tests recursively or constructing the test results as a constructed element and then analysing the results.  Recursion would be suitable for a simple sum of passes and fails, but it closely binds the analysis to the testing.  An intermediate document decouples testing from reporting, thus providing greater flexibility in the analysis but requiring temporary documents.  &lt;br /&gt;&lt;br /&gt;So version 2 constructed a sequence of test results, and then merged these results with the original test set to generate the report. Collating two sequences is a common idiom which in functional languages must either recurse over both, or iterate over one sequence whilst indexing into the other, or iterate over a extracted common key and index into both. The reporting is currently done in XQuery but it should be possible to use XSLT.  Either the collating would need to be done before the XSLT step or XSLT would have the collating task.  Not a happy situation.&lt;br /&gt;&lt;br /&gt;So last week in comes version 3.  Now the step which executes the tests augments each test with new attributes (pass, timing) and elements (output) and similarly each expectation with the results of its evaluation so that one single, enhanced document is produced, with the same schema as the original [the augmented data has to be optional anyway since some tests may be tagged to be ignored]. Transformation of the complete document to HTML is then straightforward either in line,in a pipeline with XQuery or XSLT.  The same transformation can be run on the un-executed test set.&lt;br /&gt;&lt;br /&gt;Augmenting the test set is slightly harder in XQuery than it would be in XSLT.  For example, after executing each test, the augmented test is recreated with:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; element test  { &lt;br /&gt;       $test/@*,&lt;br /&gt;       attribute pass {$pass},&lt;br /&gt;       attribute timems {$timems},&lt;br /&gt;       $test/(* except expected),&lt;br /&gt;       element output {$output},      &lt;br /&gt;       $expectedResults&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt; &lt;br /&gt;This approach means that, once again, handling the construction of temporary documents is a key requirement for XQUery applications.&lt;br /&gt;&lt;br /&gt;But I'm still not quite happy with version 3. As so often I'm struggling with namespaces in the test scripts - now where's my pair?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-3893961577628741877?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/3893961577628741877/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=3893961577628741877&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/3893961577628741877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/3893961577628741877'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2009/04/xquery-unit-tests.html' title='XQuery Unit Tests'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-2470093239657400736</id><published>2009-04-19T00:27:00.007+01:00</published><updated>2009-04-20T07:55:38.271+01:00</updated><title type='text'>Implementing a table look-up in XQuery</title><content type='html'>Handling temporary XML fragments in the eXist XML db has improved markedly in version 1.3.  I have been looking again at an example of processing MusicXML documents which I first wrote up in the &lt;a href="http://en.wikibooks.org/wiki/XQuery/Using_Intermediate_Documents"&gt;XQuery wikibook&lt;/a&gt;.  &lt;br /&gt;&lt;br /&gt;The code requires a translation from the note name (A, B) to the midi note value for each note. The pitch of a note is defined by a structure like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  &amp;lt;pitch&gt;&lt;br /&gt;     &amp;lt;step&gt;C&amp;lt;/step&gt;&lt;br /&gt;     &amp;lt;alter&gt;1&amp;lt;/alter&gt;&lt;br /&gt;     &amp;lt;octave&gt;3&amp;lt;/octave&gt;&lt;br /&gt; &amp;lt;/pitch&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;One approach is to use an if -then -else construct:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;declare function local:MidiNote($thispitch as element(pitch) ) as xs:integer&lt;br /&gt;{&lt;br /&gt;  let $step := $thispitch/step&lt;br /&gt;  let $alter :=&lt;br /&gt;    if (empty($thispitch/alter)) then 0&lt;br /&gt;    else xs:integer($thispitch/alter)&lt;br /&gt;  let $octave := xs:integer($thispitch/octave)&lt;br /&gt;  let $pitchstep :=&lt;br /&gt;    if ($step = "C") then 0&lt;br /&gt;    else if ($step = "D") then 2&lt;br /&gt;    else if ($step = "E") then 4&lt;br /&gt;    else if ($step = "F") then 5&lt;br /&gt;    else if ($step = "G") then 7&lt;br /&gt;    else if ($step = "A") then 9&lt;br /&gt;    else if ($step = "B") then 11&lt;br /&gt;    else 0&lt;br /&gt;  return 12 * ($octave + 1) + $pitchstep + $alter&lt;br /&gt;} ;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;but this cries out for a table lookup as a sequence:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;declare variable  $noteStep := &lt;br /&gt;(&lt;br /&gt;   &amp;lt;note name="C" step="0"/&gt;,&lt;br /&gt;   &amp;lt;note name="D"  step="2"/&gt;,&lt;br /&gt;   &amp;lt;note name="E" step="4"/&gt;,&lt;br /&gt;   &amp;lt;note name="F" step="5"/&gt;,&lt;br /&gt;   &amp;lt;note name="G" step="7"/&gt;,&lt;br /&gt;   &amp;lt;note name="A" step="9"/&gt;,&lt;br /&gt;   &amp;lt;note name="B" step="11"/&gt;&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;declare function local:MidiNote($thispitch as element(pitch) ) as xs:integer&lt;br /&gt;{&lt;br /&gt;  let $alter := xs:integer(($thispitch/alter,0)[1])&lt;br /&gt;  let $octave := xs:integer($thispitch/octave)&lt;br /&gt;  let $pitchstep := xs:integer($noteStep[@name = $thispitch/step]/@step)&lt;br /&gt;  return 12 * ($octave + 1) + $pitchstep + $alter&lt;br /&gt;} ;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;or an XML element:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;declare variable $noteStep := &lt;br /&gt;&amp;lt;steps&gt;&lt;br /&gt;   &amp;lt;note name="C" step="0"/&gt;&lt;br /&gt;   &amp;lt;note name="D" step="2"/&gt;&lt;br /&gt;   &amp;lt;note name="E" step="4"/&gt;&lt;br /&gt;   &amp;lt;note name="F" step="5"/&gt;&lt;br /&gt;   &amp;lt;note name="G" step="7"/&gt;&lt;br /&gt;   &amp;lt;note name="A" step="9"/&gt;&lt;br /&gt;   &amp;lt;note name="B" step="11"/&gt;&lt;br /&gt;&amp;lt;/steps&gt;;&lt;br /&gt;&lt;br /&gt;declare function local:MidiNote($thispitch as element(pitch) ) as xs:integer&lt;br /&gt;{&lt;br /&gt;  let $alter := xs:integer(($thispitch/alter,0)[1])&lt;br /&gt;  let $octave := xs:integer($thispitch/octave)&lt;br /&gt;  let $pitchstep := xs:integer($noteStep/note[@name = $thispitch/step]/@step)&lt;br /&gt;  return 12 * ($octave + 1) + $pitchstep + $alter&lt;br /&gt;} ;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;We could also store the table in the database since it is constant.&lt;br /&gt;&lt;br /&gt;eXist does some optimisation of XPath expressions, but it does not factor out the invariant expression &lt;span style="font-style:italic;"&gt;$thispitch/step&lt;br /&gt;&lt;/span&gt; in the XPath predicate. &lt;br /&gt;&lt;br /&gt;I wrote a &lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/UnitTest/runTests.xql?testName=Look-up%20performance%20tests"&gt;test suite&lt;/a&gt; to time these various implementations. Typically this shows that factoring the sub-expression reduces the execution time by 25%. However, even with this optimisation, the structure lookup is disappointingly slow. It is about 50% slower than the if/then expression when stored on disk, and 100% slower when in memory. &lt;br /&gt;&lt;br /&gt;This aspect of XQuery performance is important if XQuery is to be used for general application development since data structures such as indexed and associative arrays have to be represented as sequences of atomic values or elements.  This performance is not really surprising and there may be more performance to be gained by indexing the data base element.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-2470093239657400736?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/2470093239657400736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=2470093239657400736&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/2470093239657400736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/2470093239657400736'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2009/04/implementing-table-look-up-in-xquery.html' title='Implementing a table look-up in XQuery'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-7141759787063976645</id><published>2009-04-08T07:06:00.004+01:00</published><updated>2009-04-17T15:48:51.604+01:00</updated><title type='text'>XQuery module for Geodesy</title><content type='html'>I wrote my first attempt at Mercator ~ Latitude/Longitude conversion functions about 2 years ago when working in a case study for SPA2007.  Part of this was documented in the XQuery Wikibook article on &lt;a href="http://en.wikibooks.org/wiki/XQuery/Nationalgrid_and_Google_Maps"&gt;UK bus stops and Ordnance Survey coordinates&lt;/a&gt;. At the time I did not appreciate why my coordinates were just a bit off but fudged the difference.  Last month I used the same functions to map &lt;a href="http://innovate.direct.gov.uk/2009/03/10/pedalling-some-raw-data/"&gt;pedal cycle data&lt;/a&gt; but as gardens and roofs appeared to be much more dangerous than roads, I thought I'd better try harder and learnt about Helmert Transformations. &lt;br /&gt;&lt;br /&gt;My latest attempt is now available in the &lt;a href="http://code.google.com/p/xquery-examples/"&gt;XQuery Examples Google Project&lt;/a&gt; and the Wikibook article has been revised to use this module.  The formulae come mainly from the &lt;a href="http://www.ordnancesurvey.co.uk/oswebsite/gps/information/coordinatesystemsinfo/guidecontents/index.html"&gt;OS Guide to coordinate systems&lt;/a&gt;.  PHP Code on Barry Hunter's http://www.nearby.org site was also useful.The &lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/UnitTest/runTests2.xql?testName=Geodesy%20Functions"&gt;test suite&lt;/a&gt; for this module is still being added to. I have struggled with rounding, needed to get positions with sensible resolutions and for testing and I'm not yet happy. Some tests need visual inspection and there is a problem with heights.&lt;br /&gt;&lt;br /&gt;The module depends on the eXist math module, a prime candidate for cross-implementation standardization by the EXQuery initiative. In the latest version (v1-3) of the module, the math:atan2() function has parameters in the correct order (y,x) but older releases had these parameters reversed,as in v1-2.&lt;br /&gt;&lt;br /&gt;The design of the module uses elements with attributes in the same namespace as the module to define compound structures such as LatLongs, Ellipsoids and Projections. These are defined in an associated schema.  Compile-time checking in eXist is limited to checking the element name since eXist is not schema-aware although full schema-awareness would be of benefit in this module.&lt;br /&gt;&lt;br /&gt;Suggestions for additions to this module are most welcome, as of course is any review of the code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-7141759787063976645?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/7141759787063976645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=7141759787063976645&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/7141759787063976645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/7141759787063976645'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2009/04/xquery-module-for-geodesy.html' title='XQuery module for Geodesy'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-8072828814958851170</id><published>2009-04-05T07:04:00.002+01:00</published><updated>2009-04-05T08:35:17.283+01:00</updated><title type='text'>Dashboards and Widgets in XQuery</title><content type='html'>Jim Fuller's recent article on &lt;a href="http://www.ibm.com/developerworks/xml/library/x-xqdashboard/"&gt;Dashboards in XQuery&lt;/a&gt; makes a very good case for using XQuery for mashups generally. Jim's dashboard application reminded me of work I had been doing with my students last term on a configurable web page containing widgets to display NOAA weather data, RSS feeds, Google Maps and their own choice of data source. For this we used PHP with Simple XML, but to demonstrate the power of XQuery, I needed to show them the same application built on XQuery. It also seemed to me that the business dashboard would benefit from a design which split widget code from company-specific data.&lt;br /&gt;&lt;br /&gt;The basic architecture of the approach here is to create a set of generalised widgets as XQuery functions and to define the specifics of the widget in a configuration file.&lt;br /&gt;&lt;br /&gt;Here are a couple of configurations :  &lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/Dashboard2/main.xq?config=/db/Wiki/Dashboard2/config/jim.xml"&gt;jim.xml&lt;/a&gt; which is based on Jim's Dashboard example&lt;br /&gt;&lt;br /&gt;and &lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/Dashboard2/main.xq?config=/db/Wiki/Dashboard2/config/dsa.xml"&gt;dsa.xml&lt;/a&gt; which is based on our course weather display.&lt;br /&gt;&lt;br /&gt;The second example has a page refresh rate set, but I'm working on making the refresh rate widget- rather than page- specific using AJAX.&lt;br /&gt;&lt;br /&gt;In the demo interface code, each widget links to its XQuery source code and hence to the code of called functions. Widget executions are timed and there is a link to the configuration file itself. Here is a basic main script:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;import module namespace widgets = "http://www.cems.uwe.ac.uk/xmlwiki/widgets" at "widgets.xqm";&lt;br /&gt;&lt;br /&gt;declare option exist:serialize "method=xhtml media-type=text/html omit-xml-declaration=no indent=yes &lt;br /&gt;        doctype-public=-//W3C//DTD&amp;#160;XHTML&amp;#160;1.0&amp;#160;Transitional//EN&lt;br /&gt;        doctype-system=http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";&lt;br /&gt;&lt;br /&gt;let $configuri := request:get-parameter("config",())&lt;br /&gt;let $config := doc($configuri)/config&lt;br /&gt;return &lt;br /&gt;&amp;lt;html&gt;&lt;br /&gt;    &amp;lt;head&gt;&lt;br /&gt;        {$config/title}&lt;br /&gt;        &amp;lt;link rel="stylesheet" href="{$config/@css}" type="text/css"/&gt;&lt;br /&gt;   &amp;lt;/head&gt;&lt;br /&gt;   &amp;lt;body&gt;&lt;br /&gt;        &amp;lt;h1&gt;{$config/title/text()} &amp;lt;/h1&gt;&lt;br /&gt;         {&lt;br /&gt;         for $section in $config/section&lt;br /&gt;         let $component := $section/*&lt;br /&gt;         return &lt;br /&gt;          &amp;lt;div&gt;&lt;br /&gt;                 &amp;lt;h3&gt;{$section/@title/string()} &amp;lt;/h3&gt;&lt;br /&gt;                  {widgets:render($section)}&lt;br /&gt;          &amp;lt;/div&gt;&lt;br /&gt;          }&lt;br /&gt;   &amp;lt;/body&gt;&lt;br /&gt;&amp;lt;/html&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/Dashboard2/basicmain.xq?config=/db/Wiki/Dashboard2/config/jim.xml"&gt;Run it&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There are a couple of ideas used in the code. &lt;br /&gt;&lt;br /&gt;Each widget is defined by its own section in the configuration file. As a simple example, to configure the widget to get the date and time:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;section column="c2" title="Time in Bristol"&gt;&lt;br /&gt;       &amp;lt;datetime&gt;&lt;br /&gt;            &amp;lt;format&gt;EE dd/MM HH:mm&amp;lt;/format&gt;&lt;br /&gt;        &amp;lt;/datetime&gt;&lt;br /&gt;&amp;lt;/section&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The main script processes the configuration file, and each widget is rendered by calling a function of the same name.  The code for this dispatching currently uses the &lt;a href="http://exist-db.org/"&gt;eXist&lt;/a&gt; function util:eval(), within a util:catch call, to implement late binding:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;declare function widgets:render($section as element(section)) as element(div) {&lt;br /&gt;(:  dispatch section to the matching function   :)&lt;br /&gt;     let $component := $section/*[1]&lt;br /&gt;     let $widget := local-name($component)&lt;br /&gt;     let $function := concat("widgets:", $widget, "($component)")&lt;br /&gt;     return   &lt;br /&gt;       &amp;lt;div&gt;&lt;br /&gt;              {util:catch( "*", util:eval($function), &amp;lt;span&gt;Missing or bad widget.&amp;lt;/span&gt;) }&lt;br /&gt;       &amp;lt;/div&gt;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;A safer alternative would be to use typeswitch :&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;declare function widgets:render2($section as element(section)) as element(div) {&lt;br /&gt;    let $component := $section/*[1]&lt;br /&gt;    return&lt;br /&gt;        typeswitch ($component)&lt;br /&gt;            case element(datatime) return widgets:datetime($component)&lt;br /&gt;            case element(SQL) return widgets:SQL($component)&lt;br /&gt;            case element(monitor) return widgets:monitor($component)&lt;br /&gt;            ....&lt;br /&gt;            default return&lt;br /&gt;                &amp;lt;div&gt; Missing widget {local-name($component)} &amp;lt;/div&gt;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;but this needs updating every time a new widget is added to the module.&lt;br /&gt;&lt;br /&gt;To help with processing table data from different sources such as SQL, Excel and Google Spreadsheets, support functions transform these to a common XML structure.  This standard form is then transformed to its final HTML with the XSLT included in the configuration.&lt;br /&gt;&lt;br /&gt;For example here is the configuration for an SQL widget, reading data from a (readonly) MySQL database:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;section column="c2" title="Overpaid executives"&gt;&lt;br /&gt;        &amp;lt;SQL&gt;&lt;br /&gt;            &amp;lt;username&gt;cwstudent&amp;lt;/username&gt;&lt;br /&gt;            &amp;lt;password&gt;cwstudent&amp;lt;/password&gt;&lt;br /&gt;            &amp;lt;database&gt;jdbc:mysql://stocks.cems.uwe.ac.uk/Emp&amp;lt;/database&gt;&lt;br /&gt;            &amp;lt;query&gt;select ename,sal from emp where sal &amp;gt; 2000 order by sal desc&amp;lt;/query&gt;&lt;br /&gt;            &amp;lt;xsl&gt;&lt;br /&gt;                &amp;lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"&gt;&lt;br /&gt;                    &amp;lt;xsl:template match="table"&gt;&lt;br /&gt;                        &amp;lt;table border="1"&gt;&lt;br /&gt;                            &amp;lt;xsl:apply-templates select="row"/&gt;&lt;br /&gt;                        &amp;lt;/table&gt;&lt;br /&gt;                    &amp;lt;/xsl:template&gt;&lt;br /&gt;                    &amp;lt;xsl:template match="row"&gt;&lt;br /&gt;                        &amp;lt;tr&gt;&lt;br /&gt;                            &amp;lt;td&gt;&lt;br /&gt;                                &amp;lt;xsl:value-of select="ename"/&gt;&lt;br /&gt;                            &amp;lt;/td&gt;&lt;br /&gt;                            &amp;lt;td&gt;&lt;br /&gt;                                &amp;lt;xsl:value-of select="sal"/&gt;&lt;br /&gt;                            &amp;lt;/td&gt;&lt;br /&gt;                        &amp;lt;/tr&gt;&lt;br /&gt;                    &amp;lt;/xsl:template&gt;&lt;br /&gt;                &amp;lt;/xsl:stylesheet&gt;&lt;br /&gt;            &amp;lt;/xsl&gt;&lt;br /&gt;        &amp;lt;/SQL&gt;&lt;br /&gt;    &amp;lt;/section&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;and its widget code:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;declare function widgets:SQL($component as element(SQL)) as element (div) {&lt;br /&gt; &amp;lt;div&gt;&lt;br /&gt;    {&lt;br /&gt;       let $connection := sql:get-connection("com.mysql.jdbc.Driver", $component/database, $component/username, $component/password) &lt;br /&gt;       let $result :=   sql:execute($connection, $component/query, false())&lt;br /&gt;       let $table:=  widgets:sql-result-to-table($result)&lt;br /&gt;       return transform:transform($table,$component/xsl/*,())&lt;br /&gt;     }&lt;br /&gt; &amp;lt;/div&gt;&lt;br /&gt; };&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;widgets:sql-result-to-table converts the sql result to a common internal XML format:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt; declare function widgets:sql-result-to-table($result as element(sql:result)) as element(table) {&lt;br /&gt;&amp;lt;table&gt;&lt;br /&gt;  {for $row in $result/sql:row&lt;br /&gt;    return &lt;br /&gt;       &amp;lt;row&gt;&lt;br /&gt;       {for $col in $row/sql:field&lt;br /&gt;       return&lt;br /&gt;           element {$col/@name}&lt;br /&gt;                {string($col)}&lt;br /&gt;       }&lt;br /&gt;       &amp;lt;/row&gt;&lt;br /&gt;    }&lt;br /&gt;&amp;lt;/table&gt;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This simplifies the XSLT transformation to the final HTML div element.&lt;br /&gt;&lt;br /&gt;There's more to do on this framework, including adding support for access to passworded Google SS, Calendar and RSS feeds for which Jim's code will be handy. The framework also needs to support widgets from other modules and I'm not sure about the intermediate XML format and I'd like to use this more widely to layer the weather widgets as well. Getting the right split between widget code and configuration data is always tricky of course. However this framework seems quite useful and I intend to revisit some of the WikiBook examples to restructure as widgets.  &lt;br /&gt;&lt;br /&gt;I'll post the full code to the XQuery Wikibook shortly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-8072828814958851170?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/8072828814958851170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=8072828814958851170&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/8072828814958851170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/8072828814958851170'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2009/04/dashboards-and-widgets-in-xquery.html' title='Dashboards and Widgets in XQuery'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-6700906767851181069</id><published>2009-04-01T21:27:00.007+01:00</published><updated>2009-04-02T12:09:03.628+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MicroSoft Word'/><category scheme='http://www.blogger.com/atom/ns#' term='parameterization.'/><category scheme='http://www.blogger.com/atom/ns#' term='XQuery'/><title type='text'>Parameterised MS Word Documents with XQuery</title><content type='html'>It's coming round to exam time again at UWE, Bristol and as usual I've been struggling to get mine written.  The XQuery-based FOLD application (which supports staff and students in our School) generates exam front pages contain exam details such as module code and title, examination date, length and time as HTML which had to be copied (poorly) into MS Word.  This wasn't very satisfactory and it  would be better to generate a Word document with the completed front page and sample pages with headers and footers. I'd put this off as it seemed too complicated. The Word XML format wordml is one route but it looked daunting to generate for scratch. &lt;br /&gt;&lt;br /&gt;However for this application I only need to make some small edits to a base document.  The most obvious approach was to 'parameterise' the Word document with place-holders. Unique place-holders can be edited in with Word before the document is saved as XML.  Fields which are not editable in MS Word, such as the author and timestamps can be parameterised by editing the wordml directly. To instantiate a new Word document, the place-holders in the wordml are replaced with their values.&lt;br /&gt;&lt;br /&gt;Treating this as string replacement is easier than editing the XML directly, even if this was possible in XQuery. The XQuery script reads the wordml document, serializes the XML as a string, replaces the placeholders in the string with their values and then converts back to XML for output.&lt;br /&gt;&lt;br /&gt;Although this is not a typical task for XQuery and would be written in a similar way in other scripting languages, it is possible in XQuery with the help of a pair of functions which should be part of a common XQuery function library.  In eXist these are util:serialize() to convert from XML to a string and the inverse, util:parse().&lt;br /&gt;&lt;br /&gt;The function needs to replace multiple strings so we use a an XML element to define the name/value pairs:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;let $moduleCode := request:get-parameter("moduleCode",())&lt;br /&gt;..&lt;br /&gt;let $replacement :=&lt;br /&gt;&amp;lt;replacement&gt;&lt;br /&gt; &amp;lt;replace string="F_ModuleCode" value="{$moduleCode}"/&gt;&lt;br /&gt; &amp;lt;replace string="F_Title" value="{$title}"/&gt;&lt;br /&gt; &amp;lt;replace string="F_LastAuthor" value="FOLD"/&gt;&lt;br /&gt; ..&lt;br /&gt;&amp;lt;/replacement&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;and a recursive function to do the replacements:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;declare function local:replace($string,$replacements) {&lt;br /&gt;if (empty($replacements))&lt;br /&gt;then $string&lt;br /&gt;else&lt;br /&gt;  let $replace := $replacements[1]&lt;br /&gt;  let $rstring := replace($string,string($replace/@string),string($replace/@value))&lt;br /&gt;  return&lt;br /&gt;       local:replace($rstring,subsequence($replacements,2))&lt;br /&gt;};&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;After gathering the parameter values and formatting a replacement element, the new document is generated by:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;let $template := doc("/db/FOLD/doc/examtemplate.xml")&lt;br /&gt;let $stemplate := util:serialize($template,"method=xml")&lt;br /&gt;let $mtemplate := local:replace($stemplate,$replaceStrings/*)&lt;br /&gt;return&lt;br /&gt; util:parse($mtemplate)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Here the generated wordml is displayed in the browser, from where it can be saved, then loaded into Word.  I found out the directive at the front of the wordml:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;?mso-application progid="Word.Document"?&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;is used by the Windows OS to associate the file with MS Word so the media type is just the standard text/xml. However it is helpful to define a suitable default file name using a function in eXist's HTTP response module, the pair to the request module used to access URL parameters:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;let $dummy := response:set-header('Content-Disposition', concat('attachment;filename=',concat("Exam_",$moduleCode,".xml") ))&lt;br /&gt;let $dummy := response:set-header('Content-Type','application/msword')&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The document could also be saved directly to the database, or all documents generated eagerly ready for use.&lt;br /&gt;&lt;br /&gt;This approach feels like a bit of a hack, but it took only an hour to develop and is a major improvement on the previous approach.  Changes to the base document will need re-parameterisation, but that seems a small overhead for slowly changing standard documents.  XQuery forces a recursive approach to the string replacements where an iterative updating approach would avoid copying the (rather large) string, but performance is fast enough for this task, indeed in eXist string handling is very fast. My MS Office users will be happier but I still need to think about the Unix and Mac OS users.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-6700906767851181069?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/6700906767851181069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=6700906767851181069&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/6700906767851181069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/6700906767851181069'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2009/04/parameterisied-ms-word-documents-with.html' title='Parameterised MS Word Documents with XQuery'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-752974725705556119</id><published>2009-04-01T09:56:00.006+01:00</published><updated>2009-04-01T21:27:04.781+01:00</updated><title type='text'>Review of IBM developerWorks article by Brian Carey</title><content type='html'>I've just come across an article published by IBM's developerWorks &lt;a href="http://www.ibm.com/developerworks/library/x-presXQuery/"&gt;"Use XQuery for the presentation layer"&lt;/a&gt;  by Brian Carey.  This illustrates the value of storing complex data in XML form and using XQuery to select and transform to HTML.  Whilst the main message is well-presented, the implementation, below layers of Java, is over-complicated in a couple of ways.&lt;br /&gt;&lt;br /&gt;Brian makes the curious observation under the heading &lt;span style="font-weight: bold;"&gt;Using XQuery prevents "cheating"&lt;/span&gt;  that &lt;span style="font-style: italic;"&gt;"You cannot write business logic in XQuery because XQuery focuses exclusively on querying and transformation".&lt;/span&gt;  This rather ignores the fact that a significant number of applications are built soley on XQuery as the server-side language.  The consequence is that a simple Web application retains a complex and unnnecessary Java middle tier acting as Controller in an MVC architecture.&lt;br /&gt;&lt;br /&gt;Brian's web application provides a browsing interface to a collection of products using AJAX to update the page and XQuery to select producats and transfrom to an HTML table.&lt;br /&gt;&lt;br /&gt;Implemented in XQuery on the open source&lt;a href="http://exist-db.org/"&gt; eXist&lt;/a&gt; XML database as an example, we need only use the HTTP interface functions provided to couple the HTTP requests directly to the XQuery script.  For eXist the additions would be:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;declare variable $docName as xs:string := "lures.xml";&lt;br /&gt;declare variable $configuration as xs:string := request:get-parameter("configuration",());&lt;br /&gt;declare variable $usage as xs:string:= request:get-parameter("usage",());&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;It might be objected that this script binds the resources and interfaces too closely to the script. Indeed the only benefit of the Java controller layer is this de-coupling.  We can achieve the same effect in  XQuery with a local configuration file to aid portability and testing:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;ConfigurationFile&gt;&lt;br /&gt;   &amp;lt;lureFileName&gt;/db/Wiki/BC/lures2.xml&amp;lt;/lureFileName&gt;&lt;br /&gt;&amp;lt;/ConfigurationFile&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;and adding these lines to the XQuery script:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;declare variable $config := /ConfigurationFile;&lt;br /&gt;declare variable $docName := $config/lureFileName;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I've implemented Brian's code with eXist on the XQuery Wikibook server and the relevant scripts are here:&lt;br /&gt;&lt;a href="http://www.cems.uwe.ac.uk/%7Ecjwallac/apps/BC/index.html"&gt;&lt;br /&gt;http://www.cems.uwe.ac.uk/~cjwallac/apps/BC/index.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I changing only the script address in the HTML code and  correcting an error in the AJAX function where request.readyState was miss-typed. (took me a while to track that down!).  Middle layer all gone.  Storage of the whole application in eXist would be a normal deployment but was not possible without editing because the HTML page is not valid XHTML .&lt;br /&gt;&lt;br /&gt;One impediment to the use of XQuery as an application development language is that functions to extend the XPath function with functionality such as HTTP interfacing are implementation-dependent, limiting portability.  A new inititive &lt;a href="http://www.exquery.org/"&gt;EXQuery&lt;/a&gt; seeks to remedy this problem by developing a cross-platform library.&lt;br /&gt;&lt;br /&gt;One other feature of  Brian's implementation is the structure of the XML file.  The start of the file looks like&lt;br /&gt;&lt;br /&gt;&amp;lt;lures&gt;&lt;br /&gt;   &amp;lt;casting&gt;&lt;br /&gt;       &amp;lt;minnows brand="Yohuri" style="deep" size="3"&gt;&lt;br /&gt;           &amp;lt;minnow color="midnight blue"&gt;&lt;br /&gt;&lt;code&gt;&lt;lures&gt;&lt;/lures&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;But since the data  is intended to be searched for usage(e.g. casting) and configuration (e.g. minnow)  this leads to XQuery code like&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;if ($configuration = 'minnow' and $usage = 'casting') then&lt;br /&gt;for $minnows in doc($docName)//casting/minnows&lt;br /&gt;return&lt;br /&gt;&lt;/code&gt;&lt;div&gt;&lt;br /&gt;else&lt;br /&gt;else if ($configuration = 'minnow' and $usage = 'trolling') then&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;..&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;and because the child structures are actually all the same, this leads to unmaintableable and repetative code.&lt;br /&gt;&lt;br /&gt;A fix is possible in XQuery using local-name to filter using the node names themselves.  A better approach would be to flatten the whole file, changing the representation of the configuration and usage concepts from elements to attributes:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;lures&gt;&lt;br /&gt;   &amp;lt;lure brand="Yohuri" style="deep" size="3" color="midnight blue" usage="casting" configuration="minnow"&gt;&lt;br /&gt;&lt;br /&gt;..&lt;lures&gt;&lt;lure brand="Yohuri" style="" size="3" color="midnight blue" usage="casting" configuration="minnow"&gt;&lt;/lure&gt;&lt;/lures&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;and the query becomes&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  for $lure in doc($docName)//lure[@configuration = $configuration][@usage=$usage]&lt;br /&gt;  return ..&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In summary, this implementation might be a "cheat" but cheating by reducing complexity and lines of code seems a good thing to do.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-752974725705556119?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/752974725705556119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=752974725705556119&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/752974725705556119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/752974725705556119'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2009/04/review-of-ibm-developerworks-article-by.html' title='Review of IBM developerWorks article by Brian Carey'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-5971237119503173749</id><published>2009-02-23T10:47:00.004Z</published><updated>2009-04-03T11:20:11.180+01:00</updated><title type='text'>Data Normalization</title><content type='html'>My lastest teaching program is for model inference from un-normalized data.  This had its inception in a PHP tool written some years ago. The new version uses my ER XML schema to integrate the output with the other data modelling tools. &lt;br /&gt;&lt;br /&gt;Normalisation is usually taught on data base courses via the abstract concepts of first, second third normal and higher normal forms. In my introductory module I just want to get over the basic idea of reduction in data duplication through the actual factorisation of a first normal-form table (atomic values) into a set of related third normal-form tables.&lt;br /&gt;&lt;br /&gt;Here is the tool, written of course in XQuery:&lt;br /&gt;&lt;br /&gt;&lt;a href=" http://www.cems.uwe.ac.uk/xmlwiki/ER/normalizer.xq"&gt; http://www.cems.uwe.ac.uk/xmlwiki/ER/normalizer.xq&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I get the students to take a nominated data set, factorise it, generate the SQL table declaration and INSERT statements, load them into a MySQL database and then reconstruct the original table using a select statement joining all the tables. This allows the student to check that the factorisation is loss-less but of course it does not check that it is optimal. At present the tool allows the student to explore different possibilities and create any factorisation they like. &lt;br /&gt;&lt;br /&gt;The state of the factorisation is the current dataset URI and the current factorisation, defined by an ER model. Currently these are passed between client and server in the URL. This limits the size of the model and i guess I should change to POST but the interface behavior will not be as clean (the back button works as a simple Undo) and I can't have simple generated links on buttons. I guess I need help in interface programming here.&lt;br /&gt;&lt;br /&gt;For the record, the code is 600 lines split into 27 functions and using two functions in the larger er module to transform the XML model to DDL and an ER diagram. Code by request until I find a suitable home.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-5971237119503173749?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/5971237119503173749/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=5971237119503173749&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/5971237119503173749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/5971237119503173749'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2009/02/data-normalization.html' title='Data Normalization'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-1245000325208207317</id><published>2009-02-06T07:39:00.003Z</published><updated>2009-02-08T18:07:41.868Z</updated><title type='text'>Data Modelling Tutor</title><content type='html'>The SQL tutor is now in use and seems to be finding favour with students and other tutors. There is a long list of things to add, like the ability to discuss an exercise but the course moves on and now I want to apply the same ideas to the teaching of data modelling. Students often find this rather difficult.&lt;br /&gt;&lt;br /&gt;For the past few years we have used an excellent case tool called QSEE, developed by Mark Dixon at Leeds Metropolitan University. We have mainly used this multi-diagram tool for the ER diagrams. QSEE supports conceptual ER models and handles foreign keys, link tables and week entities when generating the SQL DDL. I have a running battle with some other tutors over the use of conceptual ER diagrams versus Relational ER Diagrams, complete with foreign keys and link tables. In my multi-paradigm teaching, conceptual models which treat the later as artefacts of a relational data model makes more sense. Of course I'd like to see a few improvements but sadly development of this tool seems to have ceased. Pity that it hasn't been open sourced.&lt;br /&gt;&lt;br /&gt;My teaching emphases the difference between a model and its various representations as diagrams, as text and as code. Since we have already studied XML, it is natural to think of representing the conceptual data model as an XML document and writing the transformations in XSLT or XQuery. Having used Graphviz for a number of years the XML can be transformed to the dot notation to create diagrams in different diagraming conventions. Moreover the goal of providing an interactive data modeling tutor seems more easily realised by processing textual descriptions.&lt;br /&gt;&lt;br /&gt;So this weekend, snowed in from work on the boat, I've been working on this tutor and data modelling tool.  The really hard part has been to write  the model comparator so that differences between a student model and the 'master' model can be detected and explained.  This has to take account of variations in the names the student may use as well as differences in order of definition, so a straight XML diff isn't enough.  What I have now is not quite right but it will have to be good enough  if I want to get this tutor out  to students this week.&lt;br /&gt;&lt;br /&gt;So here is the link to the index of worksheets so far written:&lt;br /&gt;&lt;br /&gt;http://www.cems.uwe.ac.uk/xmlwiki/ER/index.xq?tag=ER&lt;br /&gt;&lt;br /&gt;The transformations currently supported include Chen diagrams, ER diagrams with or without attributes, SQL DDL, SQL DDL with foreign keys and many-many resolution, and a rather clunky English text representation.&lt;br /&gt;&lt;br /&gt;One feature which was unplanned and just emerged as an obvious addition, was the ability to provide a default model template so the student could solve initial problems by filling in the blanks rather than starting with a blank page.&lt;br /&gt;&lt;br /&gt;There is still a lot to do, but I'm pleased to have got the prototype of the ground - a long-held idea finally coming to fruition -  made possible by the power of XQuery and the eXist XML database, for which I give thanks to Wolfgang and and the guys every day.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-1245000325208207317?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/1245000325208207317/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=1245000325208207317&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/1245000325208207317'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/1245000325208207317'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2009/02/data-modelling-tutor.html' title='Data Modelling Tutor'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-4653612816566073267</id><published>2009-01-23T22:57:00.004Z</published><updated>2009-01-24T08:00:11.105Z</updated><title type='text'></title><content type='html'>Some years ago I wrote an SQL  workbook  which was used on a couple of courses, but although it had an interactive interface so that that a student could test their SQL statements against the example database,  the results were not checked.  I planned to create an interactive site which would present  tasks to the student, accept the SQL statement input, execute the statement and compare the result with that of the model answer.  Since I was teaching PHP/MySQL at the time, in good dog-fooding tradition, I started on an implementation using this platform, but it got sticky and stalled.  Then I discovered XQuery and the other day, wrote an XQuery/ eXist implementation.&lt;br /&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/SQLTutor/help.html"&gt;&lt;br /&gt;http://www.cems.uwe.ac.uk/xmlwiki/SQLTutor/help.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[I'm really supposed to be marking but I find my most creative streak when marking's about - the root perhaps of the love/hate relationship I have with my job.]&lt;br /&gt;&lt;br /&gt;The relative ease with which this version was created well illustrates the power of the XQuery/ Native XML database development approach.  This application lies in the sweet spot for this technology and here is why I think that is:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;XML handles Composition&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Each worksheet is represented by an XML document.  The document describes properties of the worksheet - database used, title, tags  and each of the steps in the worksheet.  It is too weak to say that steps are part of the worksheet, they -are- the worksheet.  A normalised relational implementation requires one table for the worksheet properties , another for the steps and a foreign key to link these two types together. This artifical separation into master and child records complicates the model and its processing. A symptom of the need for a composition can be found in the naming problem - what do you call the master table - &lt;span style="font-weight: bold;"&gt;worksheet&lt;/span&gt; perhaps? But that's not right - in domain terms a worksheet is the master record AND its children as a single entity. &lt;span style="font-weight: bold;"&gt;worksheetBody?&lt;/span&gt; - yeech.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;XML handles order&lt;/span&gt;&lt;br /&gt;The Steps in a worksheet are ordered. To represent this in SQL requires an additional  sequence number . Then editing to insert and delete steps requires re-numbering.  In XML, order is implicit in the document order of the steps.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;XML handles heterogeneity&lt;/span&gt;&lt;br /&gt;Steps in a worksheet are different types. Some are simple explanations, some are demonstrations of SQL constructs, many are exercises and others have yet to be designed&lt;span style="font-weight: bold;"&gt;.&lt;/span&gt;  A relational approach would either coerce all types  into a common structure, with lots of null fields,&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;or use multiple tables, one for each type, and a super-type table. [Object-relational databases support a more transparent implementation but who uses those?]&lt;span style="font-weight: bold;"&gt;.  &lt;/span&gt;In XML, different types of Step  &lt;span style="font-weight: bold;"&gt;c&lt;/span&gt;an be freely interleaved in the step sequence.&lt;span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;XML handles multi-valued attributes&lt;/span&gt;&lt;br /&gt;As with most of my applications these days, I use tags to support searching and classifying resources.  In a normalised relational database, I should break these out into a separate table with a foreign key, but would probably fudge the problem by putting all tags into an arbitrarily concatenated field.  In XML tags are simply repeated elements with no temptation to step outside the data model.&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;XML supports documents&lt;/span&gt;&lt;br /&gt;Worksheets are standalone entities, which are authored, edited, deployed, removed as units. In a relational approach, all worksheets would be stored in common database tables, and the domain concept of worksheet as a unit is  lost.  This is particularly a problem in development:  in the SQL tutor, worksheets may either be located in the XML database but may also be accessed from anywhere on the web - it makes little difference to the script providing the interactive interface. So new worksheets can be tested before installation with ease.&lt;span style="font-weight: bold;"&gt;  &lt;/span&gt;They can also be exchanged, encouraging reuse and standardisation&lt;span style="font-weight: bold;"&gt;.&lt;br /&gt;&lt;br /&gt;XML Documents are human-editable&lt;br /&gt;&lt;/span&gt;My PHP/MySQL prototype stalled on the need to develop an interactive editor for worksheets in additon to  the interactive tutor.  In XML this component is not required, provided of course that the worksheet author is happy to author XML. If not, there are generic editors available to assist.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;XQuery handles XML natively.&lt;/span&gt;&lt;br /&gt;Inputs - the script, the SQL table returned by the SQL interface and the XHTML conent of some step properties - and the output - XHTML pages - are all XML structures. A language which handles XML natively does not have perform the re-structuring required in , say, PHP before it can be processed [PHP- XML interfaces have made this somewhat less difficult].&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;XQuery handles comples processing.&lt;/span&gt;&lt;br /&gt;XQuery is much more than the XML equivalent of SQL .The SQL tutor has the task of testing whether two results are functionally the same.  Two tables are the same if the column headings are different, but the data the same, or if columns are in different orders, or if rows in an SELECT statement with no ORDER BY clause  are in a different order.  The sequence and element structures of the XML data model  combined with the expressiveness of XQuery make this computation straightforward to code.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;A Native XML database supports development&lt;br /&gt;&lt;/span&gt;I struggle with the design of the Worksheet schema. Minor additions occur all the time as my ideas develop, but since eXist is schema-independent, I can make these changes bottom-up before I need to formalise them as a schema. In a relational database I'm forced to work top-down, schema first.  Moreover I feel safe that if I have a major redesign, an XSLT transformation will do the necessary schema evolution of existing Worksheets.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;This case study demonstrates that a relational database is a poor technology for implementing a tutorial about SQL.  This asymetry is not the case for XQuery, and the next project is to modify the tutor to do the same for XQuery expressions.&lt;br /&gt;&lt;br /&gt;The tutor goes into use with 200 students next week although the worksheets themselves could do with more revision. Since the tutor logs all input, it will be interesting to be able to see what kinds of error are made, and then be able to adjust the hinting accordingly. Wish me luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-4653612816566073267?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/4653612816566073267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=4653612816566073267&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/4653612816566073267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/4653612816566073267'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2009/01/some-years-ago-i-wrote-sql-workbook.html' title=''/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-7542153310782805815</id><published>2008-11-02T23:40:00.003Z</published><updated>2008-11-02T23:51:59.853Z</updated><title type='text'>Listen to Twitter</title><content type='html'>Finding myself working but wanting to know how Lewis Hamilton was getting on, I wondered if Twitter would be able to let me know.  I was looking for interesting feeds for the students, so I knocked up a bit of XQuery to fetch the atom feed for a Twitter search and turn that into Voice+XML for use with Opera.  Works pretty well even if it is rather unsophisticated and uses page refresh rather than AJAX.  The script uses the md5 hash of the last tweet spoken to know what new tweets there are.  I plan to have this running on Tuesday in the lecture. One problem is that it only works if the Opera window is active so I can't have it running in the background. However the main problem is that tweets don't indicate the language so a lot of very poor, and probably disappointed Portugese is being tweeted now on the Hamilton stream.&lt;br /&gt;&lt;br /&gt;http://www.cems.uwe.ac.uk/xmlwiki/Twitter/vsearch.xq?search=Lewis+Hamilton&amp;amp;seconds=30&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-7542153310782805815?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/7542153310782805815/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=7542153310782805815&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/7542153310782805815'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/7542153310782805815'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2008/11/listen-to-twitter.html' title='Listen to Twitter'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-4829891792316834689</id><published>2008-10-26T18:49:00.004Z</published><updated>2008-10-27T07:20:32.020Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='semantic web'/><category scheme='http://www.blogger.com/atom/ns#' term='SKOS'/><category scheme='http://www.blogger.com/atom/ns#' term='SPARQL DBpedia'/><title type='text'>Wikipedia Categories for Posters</title><content type='html'>I'd planned to extend the Alphabet maker into a site that assisted Charlie to find appropriate names by inducing the category of terms and then either warning about names not in the category, or correcting spelling based on names in that category, or even suggesting a name for a missing letter.&lt;br /&gt;&lt;br /&gt;First I thought  I should understand the categories available in dbPedia and started with the Wikipedia categories using the skos vocabulary . I wrote a small skos-based browser:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/RDF/skosbrowse.xq?action=help"&gt;http://www.cems.uwe.ac.uk/xmlwiki/RDF/skosbrowse.xq?action=help&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This has two pages: a category page showing the category, the list of resources in that category with broader and narrower categories and a resource  page showing the English abstract and the Wikipedia thumbnail if there is one.&lt;br /&gt;&lt;br /&gt;From a category, you can link to a gallery of all thumbnails for resources in that category, and hence to a random Alphabet poster based on that category.  There is a significant proportion of dead links among the thumbnails however and I need to look-ahead to exclude them.&lt;br /&gt;&lt;br /&gt;One feature of this application which I haven't seen elsewhere (I live a sheltered life!) is the use of key-bindings to perform common searches on selected text.  Text selected in the abstract can, with one key-stoke, link to Wikipedia, Google, Google Maps or Google Images.  I like the idea of giving more control to the user over what is linked, and I have implemented this on my prototype presentation software which I'm trialling on a couple of courses to see if students find this useful.&lt;br /&gt;&lt;br /&gt;Browsing around dbPedia using Wikipedia categories and foaf:depiction is not without its problems.  For example the category &lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/RDF/skosbrowse.xq?category=Amphibians"&gt;Amphibians&lt;/a&gt;  includes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;common names of amphibians - Cave Salamander&lt;/li&gt;&lt;li&gt;species of amphibians - Gerobactrus&lt;/li&gt;&lt;li&gt;groups, families and orders of Amphibians - Oreolalax&lt;/li&gt;&lt;li&gt;parts of amphibians  - Vocal Sac&lt;/li&gt;&lt;li&gt;lists of amphibians - List of all Texas amphibians&lt;/li&gt;&lt;li&gt;lists of related subjects -  &lt;span style="font-size:100%;"&gt;Federal Inventory of Amphibian Spawning Areas&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;This puts me in mind of &lt;a href="http://www.multicians.org/thvv/borges-animals.html"&gt;Borges' invention&lt;/a&gt; of a Chinese classification of animals. Aren't categories like "suckling pigs" and "those that from a long way off look like flies"  just delicious?  However, erhaps a subject's other categories might help but there is no "List" category for example, so no way to disambiguate the various usages of a category.&lt;br /&gt;&lt;br /&gt;foaf:depiction has a similar problem. The &lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/RDF/skosgallery.xq?category=Modern_painters"&gt;Modern Painters &lt;/a&gt;category shows a equal mixture of depictions of the painter and depictions of works by the painter, with a few depictions of where the artist lived. This is particularly confusing when the image is a portrait! However, these categories are much cleaner than others, if somewhat incomplete.&lt;br /&gt;&lt;br /&gt;It has often been observed that tools based on dbPedia should help to improve Wikipedia. For example it is clear that the &lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/RDF/skosbrowse.xq?category=Painters_by_nationality"&gt;Painters by Nationality&lt;/a&gt;&lt;br /&gt;should not have any Painter resources, so it would be nice to use this interface to edit the categories of the two errant painters directly from an interface like this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-4829891792316834689?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/4829891792316834689/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=4829891792316834689&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/4829891792316834689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/4829891792316834689'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2008/10/wikipedia-categories-for-posters.html' title='Wikipedia Categories for Posters'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-2886377874538754049</id><published>2008-10-22T23:35:00.005+01:00</published><updated>2008-10-23T00:50:04.888+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xquery gift'/><title type='text'>Alphabet Poster</title><content type='html'>&lt;p&gt;Grandson Charlie (age nearly 6) rang the other night to tell me the animals he had found for the animal alphabet we had discussed the previous night.  I thought it would be a neat present to make a program to create a poster by fetching images from the web for each of his words and lay it out as a poster. I like the idea of writing programs as gifts, but Charlie would prefer something real- like a climbing wall!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I thought of using Flickr, or Google images, then settled on using Wikipedia, searched via dbpedia. &lt;/p&gt;                         &lt;p&gt;There are generally two images included in the dbpedia data - foaf:img - a full size JPEG image and foaf:depiction a GIF thumbnail.  The  thumbnails are fine for this job.&lt;/p&gt;                         &lt;p&gt;The SPARQL query to get  the thumbnail for an image is rather simple:&lt;/p&gt;&lt;p&gt;PREFIX : &amp;lt;http://dbpedia.org/resource/&gt;&lt;br /&gt;PREFIX foaf: &amp;lt;http://xmlns.com/foaf/0.1/&gt;&lt;br /&gt;SELECT * WHERE {&lt;br /&gt;      :Hedgehog  foaf:depiction ?img.&lt;br /&gt;   }&lt;http: org="" resource=""&gt;&lt;http: com="" foaf="" 1=""&gt;&lt;/http:&gt;&lt;/http:&gt;&lt;/p&gt;                         &lt;p&gt;The XQuery script parses the list of words and for each word, uses this query to get the uri of the wikipedia image.  The trickiest part was laying out the poster.  I struggled to do the  gallery layout in CSS alone but could not get this to work with an image + caption. In the end I reverted to a table layout with a width parameter.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The functional XQuery requires the layout to be done in two stages: first generate the table cells in the right, sorted order.  Then compute the number of rows required for the given number of columns and generate the table, indexing into the cell sequence to layout the cells in order. In an imperative language, or a language which did not require that every constructed element was well-formed, the two task can be merged. The approach necessitated by the functional language feels cleaner but I'd prefer to write this as a pipeline: sort the words &gt; generate the image cells &gt; layout the table without the need to resolve the structure clash (a Jackson Structured Programming term) between the image order and the table order  via a random access into a sequence.  The co-routines in Python would make a better solution I feel.  XML Pipelines might help but they feel too heavyweight for this minor task.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/RDF/alphabet.xq?action=poster&amp;amp;title=Charlie%27s+Animal+Alphabet&amp;amp;cols=4&amp;amp;alphabet=Ant%2C+Bat%2C+Chimpanzee%2C+Donkey%2C+Elephant%2C+Iguana%2C+Jellyfish%2C+Monkey%2C+Newt%2C+Fox%2C+Giraffe"&gt;Charlies Animals&lt;/a&gt; so far.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The XQuery Script is in the &lt;a href="http://en.wikibooks.org/wiki/XQuery/Alphabet_Poster"&gt;Wikibook&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-2886377874538754049?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/2886377874538754049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=2886377874538754049&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/2886377874538754049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/2886377874538754049'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2008/10/grandson-charlie-age-nearly-6-rang.html' title='Alphabet Poster'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-1696190441010763821</id><published>2008-09-22T16:30:00.002+01:00</published><updated>2008-09-22T23:51:27.502+01:00</updated><title type='text'>RDF Vocab work</title><content type='html'>I'm off to Oxford to learn about RDF Vocabularies at the &lt;a href="http://vocamp.org/wiki/VoCampOxford2008"&gt;Oxford Vocamp. &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;My own meanderings in this field have been limited to a rather hacked Vocabulary Browser written in XQuery:&lt;br /&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/Vocab/index.xq"&gt;&lt;br /&gt;http://www.cems.uwe.ac.uk/xmlwiki/Vocab/index.xq&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;and my rather limited attempts to provide an RDF extract from the FOLD  Information System.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://www.cems.uwe.ac.uk/wiki/index.php/FOLD/RDF"&gt;https://www.cems.uwe.ac.uk/wiki/index.php/FOLD/RDF&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;with a current dump of the RDF&lt;br /&gt;&lt;br /&gt;http://www.cems.uwe.ac.uk/~cjwallac/FOLD/all2008.rdf&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-1696190441010763821?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/1696190441010763821/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=1696190441010763821&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/1696190441010763821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/1696190441010763821'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2008/09/rdf-vocab-work.html' title='RDF Vocab work'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-1032472089182932492</id><published>2008-03-01T09:08:00.002Z</published><updated>2008-03-01T11:14:38.136Z</updated><title type='text'>SPARQLing Country Calling Codes</title><content type='html'>Stimulated by Henry Story's &lt;a href="http://blogs.sun.com/bblfish/entry/sparqling_calling_codes"&gt;blog entry&lt;/a&gt;, I wrote the equivalent in XQuery, and in doing so, bumped into some issues with the dbpedia data. In particular, there is no category I could find to identify a country, but then what constitutes a country depends on what the geographical entity is classified for, so this is to be expected.&lt;br /&gt;&lt;br /&gt;In the end I resorted to scraping the wikipedia page which lists the codes directly.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikibooks.org/wiki/XQuery/SPARQLing_Country_Calling_Codes"&gt;Wikibook module  &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-1032472089182932492?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/1032472089182932492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=1032472089182932492&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/1032472089182932492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/1032472089182932492'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2008/03/sparqling-country-calling-codes.html' title='SPARQLing Country Calling Codes'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-9211116280071138889</id><published>2008-02-28T08:25:00.003Z</published><updated>2008-02-28T08:50:48.379Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='XQuery SMS'/><title type='text'>XQuery SMS service</title><content type='html'>I've recently resurrected our two-way SMS service for use by my students in their current coursework, a site to gather and report results for their chosen team sport.  I require an exotic interface to the data, for example a speech interface with Opera or an SMS interface.  In my SMS installation, the first word in an in-coming message is used to determine the service to which the message is to be routed via HTTP, and the reply if any is then sent via our out-bound service to the originating phone.  The framework was originally implemented in PHP, but individual services can be in any language.  There are a number of mainly demonstration services implemented. XQuery is used to implement a decoder for UK vehicle license numbers. This is also a nice example of the use of regular expressions.  By comparison with the original PHP script, the XQuery version is both cleaner and more general.  However there is no regexp function in XQuery which returns the matched groups in an expression, so this is perhaps bodged with a wrapper around the XSLT2 analyze-string function.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikibooks.org/wiki/XQuery/String_Analysis#SMS_service"&gt;http://en.wikibooks.org/wiki/XQuery/String_Analysis#SMS_service&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-9211116280071138889?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/9211116280071138889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=9211116280071138889&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/9211116280071138889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/9211116280071138889'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2008/02/xquery-sms-service.html' title='XQuery SMS service'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-1533829541447208580</id><published>2008-02-13T17:18:00.003Z</published><updated>2008-02-13T17:31:21.164Z</updated><title type='text'>RDF /Sparql with XQuery</title><content type='html'>As part of my learning about RDF, Sparql and the semantic web, I thought I would take the familiar employee/department/salary grade example which I used in the XQuery/SQL comparison as a case study.  To this end I wrote two XQuery scripts:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;XML to RDF  - a script using a generic function, guided by a map , to translate flat XML tables to RDF and RDFS&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Sparql query interface - an XQuery interface to a Joseki Sparql service to allow the user to execute Sparql queries against the emp-dept RDF&lt;/li&gt;&lt;/ul&gt;This is documented in an article in the &lt;a href="http://en.wikibooks.org/wiki/XQuery/RDF_and_the_Emp-Dept_case_study"&gt;wikibook.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;http://en.wikibooks.org/wiki/XQuery/RDF_and_the_Emp-Dept_case_study&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-1533829541447208580?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/1533829541447208580/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=1533829541447208580&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/1533829541447208580'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/1533829541447208580'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2008/02/rdf-sparql-with-xquery.html' title='RDF /Sparql with XQuery'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-5626907626435701647</id><published>2008-01-14T22:38:00.000Z</published><updated>2008-01-28T16:21:36.261Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='AJAX AHAH'/><title type='text'>AJAX, AHAH and XQuery</title><content type='html'>Today [well some days ago now, this item got stuck in draft] , I came across the abbreviation AHAH to refer to the  style of using AJAX to request XHTML fragments to be inserted into an HTML page.  The example of XQuery and AJAX to search employee data in the &lt;a href="http://en.wikibooks.org/wiki/XQuery/Employee_Search"&gt;wikibook&lt;/a&gt; used this pattern - like the gentleman in &lt;a href="http://en.wikipedia.org/wiki/Moli%C3%A8re" title="Molière"&gt;Molière&lt;/a&gt;'s play, I had been speaking AHAH all these years without realising it .&lt;br /&gt;&lt;br /&gt;I also happened on an item in &lt;a href="http://cse-mjmcl.cse.bris.ac.uk/blog/2008/01/11/1200048878639.html"&gt;Mark McLaren's blog&lt;/a&gt; in which he describes the use of  this pattern to provide an i&lt;a href="http://cse-mjmcl.cse.bris.ac.uk/periodicTableSuggest2/"&gt;ncremental search &lt;/a&gt;of the chemical elements.  He advocates using a JavaScript library such as script.aculo.us but I'm not sure this library is warranted for a simple task like this (tempting fate here I fear).  For teaching purposes, minimal code is best I feel. So I implemented a version using XQuery and minimal JavaScript.&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/ajax/periodicTable.xq"&gt;&lt;br /&gt;&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/ajax/periodicTable.xq"&gt;The incremental search&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikibooks.org/wiki/XQuery/Incremental_Search_of_the_Chemical_Elements"&gt;The WikiBook page&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;XQuery and AHAH make a pretty good pair I think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-5626907626435701647?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/5626907626435701647/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=5626907626435701647&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/5626907626435701647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/5626907626435701647'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2008/01/ajax-ahah-and-xquery.html' title='AJAX, AHAH and XQuery'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-6587393210989219061</id><published>2008-01-12T19:14:00.000Z</published><updated>2008-01-14T17:00:27.383Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='googlechart sparkline'/><title type='text'>GoogleChart API and sparklines</title><content type='html'>As a long-time fan of Edward Tufte's work, I've often wanted to make use of his &lt;a href="http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0001OR&amp;amp;topic_id=1"&gt;sparkline&lt;/a&gt; idea, but haven't come across  a suitable tool to make them.  Now the &lt;a href="http://code.google.com/apis/chart/"&gt;GoogleChart API&lt;/a&gt; can generate these and a plethora of other chart types via a web service.&lt;br /&gt;&lt;br /&gt;Here is an XQuery script to demo the interface, using the character-based simple encoding of the data:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/Graph/randomSparkline.xq"&gt;Random sparkline&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikibooks.org/wiki/XQuery/GoogleChart_example"&gt;Wikibook page&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;I have one small problem - I don't know how to get rid of the axes.&lt;br /&gt;&lt;br /&gt;Later&lt;br /&gt;&lt;br /&gt;I've just discovered the undocumented chart type lfi so the sparkline can be shown without the axes - I found out from  &lt;a href="http://24ways.org/2007/tracking-christmas-cheer-with-google-charts"&gt;Brain Suda's blog&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-6587393210989219061?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/6587393210989219061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=6587393210989219061&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/6587393210989219061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/6587393210989219061'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2008/01/googlechart-api-and-sparklines.html' title='GoogleChart API and sparklines'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-8293794093783973493</id><published>2008-01-10T21:24:00.000Z</published><updated>2008-01-11T00:53:26.069Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='AIS'/><title type='text'>AIS</title><content type='html'>As we start to think about the equipment we need aboard Aremiti, the Westerly ketch we are currently re-fitting, one new item that is on our shopping list is &lt;a href="http://en.wikipedia.org/wiki/Automatic_Identification_System"&gt; AIS&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;All vessels over 300 tons and passenger vessels over 100 tons are required to carry an AIS transmitter. This broadcasts vessel  data such as identification, location, speed and course on a VHF frequency.  This is picked up by shore or vessel-based receivers and decoded into &lt;a href="http://en.wikipedia.org/wiki/NMEA_0183"&gt;NMEA&lt;/a&gt; sentences.  The data can then be used to map the vessel on a electronic chart or radar or combined with a receiving vessel's own location and course, in collision avoidance.  AIS data may also be broadcast by or on behalf of static navigational aids like lighthouses and buoys. &lt;br /&gt;&lt;br /&gt;There are a number of manufacturers of  AIS 'engines' (receiver/decoders) : &lt;a href="http://www.nasamarine.com/AIS/AIS.html"&gt;NASA&lt;/a&gt; (misleadingly called a 'radar' system) and &lt;a href="http://www.katas.co.uk/"&gt;KATAS; &lt;/a&gt;and software such as &lt;a href="http://www.coaa.co.uk/shipplotter.htm"&gt;Shiplotter. &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Since the setup cost for an amateur shore station is minimal,  anyone with line of sight of a busy stretch of water can set up their own.  Some publish the results on the web.&lt;br /&gt;A site which I came across tonight, &lt;a href="http://www.aisliverpool.co.uk/index.php"&gt;http://www.aisliverpool.co.uk/index.php&lt;/a&gt;&lt;br /&gt;is a wonderful example of what a enthusiastic web engineer can do with this data.  No longer is that ship in the distance a grey blob - it's a vessel with a name, a speed, a destination, a closeup  when mashed up with images from  this site or &lt;a href="http://www.vesseltracker.com/en/Home.html"&gt;http://www.vesseltracker.com/en/Home.html.&lt;/a&gt;&lt;br /&gt;and possibly a story, a history of visits and voyages.  In a small boat, that data broadcast to all and sundry could be life-or-death information to you.  That distant blob on an apparent collision course is no longer anonymous, routeless and inhuman.  If you are still uncertain about the ships intentions, it's so much less confusing to call up a vessel by name than some vague  lat/long and bearing.&lt;br /&gt;&lt;br /&gt;All this depends on the global unique, stable &lt;a href="http://www.imo.org/Facilitation/mainframe.asp?topic_id=388"&gt;IMO number&lt;/a&gt;, introduced to improve the safety of shipping.  On the web, it is this identifier which is the basis on any semantic web data and tools to bring this information together.&lt;br /&gt;&lt;br /&gt;The problem for both the above sites is to garner a modicum of funds to support the engineer's passion.  One key question for the semantic web is how to reward them for making their deep pot of information available as RDF.  It would seem so wrong to scrape their pages, tempting though it is.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-8293794093783973493?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/8293794093783973493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=8293794093783973493&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/8293794093783973493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/8293794093783973493'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2008/01/ais.html' title='AIS'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-1246834122580583297</id><published>2008-01-07T20:14:00.000Z</published><updated>2008-01-07T21:08:11.399Z</updated><title type='text'>More XQuery and Semantic web mashups.</title><content type='html'>Somewhat rested after a short, breezy holiday in Falmouth , with the server now working, I completed my two case studies of XQuery /DBpedia mashups.  Both are described in the XQuery Wikibook. The implementation is still a bit hairy, but now makes use of the SPARQL Query XML Result format, although I still find it useful to transform to tuples with named elements.&lt;br /&gt;&lt;br /&gt;The first is the mapping of the birth places of football players by club.  &lt;a href="http://en.wikibooks.org/wiki/XQuery/DBpedia_with_SPARQL_-_Football_teams"&gt;[Wikibook]&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The starting page is an index of clubs in the top English and Scottish leagues:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/RDF/clubIndex.xq"&gt;http://www.cems.uwe.ac.uk/xmlwiki/RDF/clubIndex.xq&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;The second shows the discography of rock artists and groups, shown as an HTML table and  using SIMILE timeline. &lt;a href="http://en.wikibooks.org/wiki/XQuery/DBpedia_with_SPARQL_and_Simile_Timeline_-_Album_Chronology"&gt;[Wikibook]. &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The starting page is an index of artists in a selected Wikipedia category, by default the Rock and Roll Hall of Fame:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/RDF/groupIndex.xq"&gt;http://www.cems.uwe.ac.uk/xmlwiki/RDF/groupIndex.xq&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-1246834122580583297?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/1246834122580583297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=1246834122580583297&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/1246834122580583297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/1246834122580583297'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2008/01/more-xquery-and-semantic-web-mashups.html' title='More XQuery and Semantic web mashups.'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-7758472146931738145</id><published>2007-12-31T08:49:00.000Z</published><updated>2007-12-31T08:59:56.415Z</updated><title type='text'>Servers down</title><content type='html'>Wouldn't you just know it?  I no sooner blog about XQuery for Semantic web mashups  than  the servers in my department at the university go off-line and I guess they might not be back up now till the 2nd.  About time we had eXist-db server space in the Cloud I say. I wonder if Amazon would be interested?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-7758472146931738145?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/7758472146931738145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=7758472146931738145&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/7758472146931738145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/7758472146931738145'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/12/servers-down.html' title='Servers down'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-793908725851277758</id><published>2007-12-30T15:28:00.000Z</published><updated>2007-12-30T23:47:58.441Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SPARQL DBpedia Simile'/><title type='text'>DBpedia and Simile Timeline</title><content type='html'>Simile &lt;a href="http://simile.mit.edu/timeline/"&gt;Timeline &lt;/a&gt;provides a neat way to display events and we have been using it on the FOLD project and on the DSA module to represent the events in the life of music artists and groups, with data extracted by hand from a copy of the Rolling Stones Review.  Having discovered DBpedia, it seems obvious to progress to using this data source instead.  The XQuery code is presented in an article in the &lt;a href="http://en.wikibooks.org/wiki/XQuery/DBpedia_with_SPARQL_and_Simile_Timeline_-_Album_Chronology"&gt;Wikibook&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The endpoint  is&lt;br /&gt;&lt;br /&gt;http://www.cems.uwe.ac.uk/xmlwiki/RDF/groupTimeline.xq?group=&lt;br /&gt;&lt;br /&gt;and the parameter is the wikpedia page name (with underscores)&lt;br /&gt;&lt;br /&gt;Some examples:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/RDF/groupTimeline.xq?group=Eric_Clapton"&gt;Eric Clapton&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/RDF/groupTimeline.xq?group=The_Allman_Brothers_Band"&gt;The Allman Brothers Band&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Only the album cover is displayed in the pop-up, with links to Wikipedia and DBpedia.  Coverage of the minimal data required is quite good, but there are gaps, and the format of the release date varies. This is partly due to the need to encode not only the data but also the accuracy with which the date is known.  Some wikipedians have used xs:gYear and xs:gYearMonth. The xs:date format, being bigendian, seems to naturally support progressive accuracy,  but of course partial values like 2007-12 are not valid. In this example, I 've merely hacked a year out but this is not satisfactory.&lt;br /&gt;&lt;br /&gt;There is also an HTML page view of the same data,with added comment text: e.g.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/RDF/group2html.xq?group=The_Allman_Brothers_Band"&gt;The Allman Brothers Band&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A separate query creates an index, with links to both views, derived from a  Category:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/RDF/groupIndex.xq?category=Rock_and_Roll_Hall_of_Fame_inductees"&gt;Rock and Roll Hall of Fame&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmlwiki/RDF/groupIndex.xq?category=American_jazz_singers"&gt;American Jazz Singers&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The next step is to derive a set of life events for the group and group members - births, marriages and deaths - to place on a parallel timeline.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-793908725851277758?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/793908725851277758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=793908725851277758&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/793908725851277758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/793908725851277758'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/12/dbpedia-and-simile-timeline.html' title='DBpedia and Simile Timeline'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-4215620247947593233</id><published>2007-12-29T12:44:00.000Z</published><updated>2007-12-29T13:27:53.148Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SPARQL DBpedia'/><title type='text'>Football Teams, DBPedia and SPARQL</title><content type='html'>Having written a number of applications which scrape information directly from Wikipedia pages, I was delighted to discover the &lt;a href="http://wiki.dbpedia.org/About"&gt;DBpedia project&lt;/a&gt;.  Chris Bizer and his collegues have brought the rather nebulous ideal of the Semantic web to life with this RDF database built on extracted data from Wikipedia, browsable as linked data or queryable with SPARQL.  With this resource, I see how to contrast triples and SPARQL with  SQL and XML  in the DSA course.&lt;br /&gt;&lt;br /&gt;My first experiment has been to try to answer a question that has been recently prompted, in part, by the appointment of Fabio Capella as the manager of the England Football team.  My godson Oliver  and I were wondering just how international our club sides are and what better way to find out than to use the DBpedia data to create a map of the birthplaces of the players in a team.&lt;br /&gt;&lt;br /&gt;The result is described in some detail in an &lt;a href="http://en.wikibooks.org/wiki/XQuery/DBpedia_with_SPARQL_-_Football_teams"&gt;XQuery Wikibook article.&lt;/a&gt;&lt;br /&gt;Here for example are the players in the &lt;a href="http://maps.google.com/maps?q=http://www.cems.uwe.ac.uk/xmlwiki/RDF/team2kml.xq?team=Bolton_Wanderers_F.C."&gt;Bolton Wanderers team&lt;/a&gt;  shown via GoogleMap.  (you may have to refresh - there's often an initial server error ??)&lt;br /&gt;&lt;br /&gt;Being based on an extract from Wikipedia some weeks ago, this data is not quite up-to-date, there is  missing data and inconsistancies in property tagging but I couldn't do this without DBpedia - thank you guys.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-4215620247947593233?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/4215620247947593233/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=4215620247947593233&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/4215620247947593233'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/4215620247947593233'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/12/football-teams-dbpedia-and-sparql.html' title='Football Teams, DBPedia and SPARQL'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-3700890055953586955</id><published>2007-11-28T08:38:00.001Z</published><updated>2007-11-28T17:49:39.714Z</updated><title type='text'>Pipelines</title><content type='html'>Looks like its going to be the year of 'Pipes'  in my teaching. I came across &lt;a href="http://pipes.yahoo.com/pipes/"&gt;Yahoo pipes&lt;/a&gt; earlier this year and decided to restructure my second-level module, Data Schemas and Applications, around the 'web as database', before diving into local database technologies like Relational and XML databases. Yahoo Pipes provides an approachable starting point and has the added benefit  of being a technology which none of my students, from a diverse collections of programmes,  have yet encountered.  Also, those slinky pipes and typed ports are -so- seductive.&lt;br /&gt;&lt;br /&gt;However, the visual editor soon becomes awkward to use and thus leads naturally into using a scripting language instead. I started with XSLT expecting to move quickly into XQuery, but I've been surprised to find how much can be done, especially with XSLT2.0.  For a transformation engine, I've set up a service (using Saxon8 via XQuery on eXist-db).  This has allowed us to implement most of the yahoo pipes we'd written and also searches over an XML file with a single script containing a form and the search results. &lt;a href="https://www.cems.uwe.ac.uk/studentwiki/index.php/XSLT_transformation"&gt;More..&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Although many of the steps in a Yahoo pipeline can be handled within a single XSLT script, some of the processing I want to demonstrate involves processing HTML pages which are not XHTML, so I needed a tidy service too, and to be able to pipeline them together.&lt;br /&gt;&lt;br /&gt;So... I need a pipeline language, a way of visualizing the pipeline and an engine to execute the pipeline. Naturally I started to write my own, based mainly on XPL which Eric Bruchez introduced me to at &lt;a href="http://www.xmlprague.cz/program.html"&gt;XML Prague&lt;/a&gt;.    A tentative first step using an XQuery script is described in an XQuery &lt;a href="http://en.wikibooks.org/wiki/XQuery/Page_scraping_and_Yahoo_Weather"&gt;WikiBook article&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Of course this is fine as play but I need to join the real world of pipeline languages.  I suppose the main contenders are :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.w3.org/TR/xproc/"&gt;XProc&lt;/a&gt; (W3C)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.orbeon.com/ops/doc/reference-xpl-pipelines"&gt;XPL &lt;/a&gt;(in Orbeon)&lt;/li&gt;&lt;li&gt;&lt;a href="http://docs.1060.org/docs/3.3.0/book/solutiondeveloperguide/doc_guide_dpml_introduction.html"&gt;DPML &lt;/a&gt;(in  NetKernel &lt;a href="http://1060.org/"&gt;&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;NetKernel looks theoretically and practically very interesting and what's more,  &lt;a href="http://1060.org/"&gt;1060research&lt;/a&gt; are a locally-based spin-off from HP labs next door.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-3700890055953586955?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/3700890055953586955/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=3700890055953586955&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/3700890055953586955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/3700890055953586955'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/11/pipelines.html' title='Pipelines'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-8351108350895759009</id><published>2007-11-24T17:59:00.000Z</published><updated>2007-11-24T19:15:12.826Z</updated><title type='text'>Topological sorting in XQuery</title><content type='html'>In the course of my attempts to implement an XQuery engine for the XML pipeline language XPL, I realized that I would need to sort the processes so that each process has its inputs available, i.e. a topological sort.&lt;br /&gt;&lt;br /&gt;Given a sequence of nodes and references with the Relax-NG schema:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    element node {&lt;br /&gt;           attribute id { xs:string },&lt;br /&gt;           element ref {&lt;br /&gt;               attribute id { xs:string }&lt;br /&gt;           }*&lt;br /&gt;       }+&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The post-condition after sorting can be defined as:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;declare function local:topological-sorted($nodes) as xs:boolean {&lt;br /&gt;   every $n in $nodes satisfies&lt;br /&gt;         every $id in $n/ref/@id&lt;br /&gt;                satisfies $id = $n/preceding::node/@id&lt;br /&gt;};&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and the recursive function to order the nodes is:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;declare function local:topological-sort($unordered, $ordered )   {&lt;br /&gt;   if (empty($unordered))&lt;br /&gt;   then $ordered&lt;br /&gt;   else&lt;br /&gt;       let $nodes := $unordered [ every $id in ref/@id satisfies $id = $ordered/@id]&lt;br /&gt;       return local:topological-sort( $unordered except $nodes, ($ordered, $nodes ))&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Sweet, eh?  Even if this implementation is not the most efficient, it has the advantage of being obviously correct. &lt;br /&gt;&lt;br /&gt;See (and improve!) the &lt;a href="http://en.wikibooks.org/wiki/XQuery/Topological_Sort"&gt;XQuery WikiBook article&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-8351108350895759009?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/8351108350895759009/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=8351108350895759009&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/8351108350895759009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/8351108350895759009'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/11/topological-sorting-in-xquery.html' title='Topological sorting in XQuery'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-580655647874888157</id><published>2007-11-18T18:05:00.000Z</published><updated>2007-11-18T18:25:21.005Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='XQuery'/><title type='text'>the Prime Sieve in XQuery</title><content type='html'>I guess I've been putting my spare effort over the past few months into the &lt;a href="http://en.wikibooks.org/wiki/XQuery"&gt;Wikibook on XQuery,&lt;/a&gt; so the blog has been very neglected.&lt;br /&gt;&lt;br /&gt;I've learnt a lot in writing the example code in the Wikibook.  The other day I bumped in the Euler Project and started on the first few the problems. &lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=3"&gt;Problem 3 &lt;/a&gt;is about primes so I had to write a prime number generator. The &lt;a href="http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes"&gt;Sieve of Eratosthenes&lt;/a&gt; in XQuery is so simple and obvious:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;declare function local:sieve($primes,$nums) {&lt;br /&gt;  if (exists($nums))&lt;br /&gt;  then &lt;br /&gt;       let $prime :=  $nums[1]&lt;br /&gt;       return local:sieve(($primes,$prime), $nums[. mod $prime !=  0])&lt;br /&gt;  else $primes&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;local:sieve((),2 to 1000)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The list of primes starts off empty, the list of numbers starts off with the integers. Each recursive call of local:sieve takes the first of the remaining integers as a new prime and reduces the list of integers to those not divisible by the prime. When the list of integers is exhausted, the list of primes is returned.&lt;br /&gt;&lt;br /&gt;Lovely but sadly not very practical for the size of numbers in the problem.&lt;br /&gt;&lt;br /&gt;Discussion and execution are in the &lt;a href="http://en.wikibooks.org/wiki/XQuery/Project_Euler#Problem_3"&gt;Wikibook.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-580655647874888157?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/580655647874888157/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=580655647874888157&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/580655647874888157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/580655647874888157'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/11/prime-sieve-in-xquery.html' title='the Prime Sieve in XQuery'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-6573210582151339072</id><published>2007-06-14T16:49:00.000+01:00</published><updated>2007-07-28T07:33:14.274+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='e-learning'/><title type='text'>Web 2.0 in teaching</title><content type='html'>This year, I've used a few of the Web 2.0 tools to enliven my courses. This year, these techniques were used on two modules, &lt;a href="http://www.cems.uwe.ac.uk/exist/shortmodspec.xql?moduleCode=UFIEKG-20-2"&gt;DSA&lt;/a&gt; and &lt;a href="http://www.cems.uwe.ac.uk/exist/shortmodspec.xql?moduleCode=UFIEP6-20-3"&gt;IAD&lt;/a&gt;.  Since I also teach web technologies, it seems appropriate that students gain some experience of these tools as part of the courses.&lt;br /&gt;&lt;br /&gt;This is a summary of the value my  students and I have found in  some of them.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Background&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The standard VLE at UWE is BlackBoard (UWEOnline).  There are a few difficulties with the way it is administered here, particularly around the restricted access to material.  Another problem is the lack of ability to link to modules or documents to UWEOnline, limiting the possibilities for integration..  Nonetheless, this the vehicle students expect to be used. Of course in this subject area  much of the material is based on server languages like PHP, MySQL, and XQuery and thus resides on our faculty server.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Blogs &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Blogs were used in two ways - as a means of communicating from teachers to students, with student commenting (&lt;a href="http://dsa2006.blogspot.com/"&gt;DSA&lt;/a&gt; and &lt;a href="http://cemsiad.blogspot.com/"&gt;IAD&lt;/a&gt;), and as a component of each students work.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Tutor blogs&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;The blogs are all hosted on Google's Blogger.  During the year this improved in ease of use an in the ability to tag any item. Thus all items on lectures, or coursework 1 or PHP can be tagged and then browsed as a group.&lt;br /&gt;&lt;br /&gt;Over the year there were over 50 posts to each blog.  The tutors on the modules all had write access.  Activity on the blogs was monitored by Google Analytics and showed the expected increase in traffic around lecture time and towards coursework hand-ins.  Since the blogs were public,there was a background of hits from all over the world, and some items, such as one on the Periodic Table of Visualisation methods were linked to and gained considerable traffic. Comments on both blogs were few, from students and the public, but there were some.&lt;br /&gt;&lt;br /&gt;I also occasionally post to my personal blog (here)and it was sometimes unclear where an item should be posted.  I also tried to run one for the new 1 -year programme in Internet Application Development but this did not take off .&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;Lessons:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Students prefer a consistent interface to learning materials, although they also valued the narrative structure of the blog.  However there are difficulties in using it to organise information which must be easily findable, even with the tagging facility.  Thus, with some reluctance,  I have decided to revert to putting lecture notes on BlackBoard rather than my own web site.  BlackBoard will also contain the workplan.  I plan to  use my own blog to add my own commentary and additional material, with items tagged for consumption by one or other module even though the blog will only be able to refer to items in BlackBoard by name.&lt;br /&gt;&lt;br /&gt;Student blogs&lt;br /&gt;&lt;br /&gt;Students on IAD were required to keep individual blogs as a record of their reading over they year. This was not successful, partly as a result of concern for the damage to reputation that poor quality web appearances could have on future prospects.  In this regard, it may be preferable to  use the private blogs in BlackBoard for this purpose.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Wikis&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;I have used wiki's for some time, and one was used for  web2.0 technologies.  It is doubtful that this was beneficial, with so much excellent material on wikipedia.  However for details of implementations and tools which are specific to CEMS, there is a need for a local wiki.  This was established as the &lt;a href="https://www.cems.uwe.ac.uk/wiki/index.php/Main_Page"&gt;CEMS wiki &lt;/a&gt;and is being populated, though much more could be done before it becomes the first palce of enquiry about the use of a language, tool or technique in CEMS.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I also set up a &lt;a href="https://www.cems.uwe.ac.uk/studentwiki/index.php/UFIEP6-20-3"&gt;student wiki in CEMS&lt;/a&gt; for use by students in organising and presenting their research into individual topics.  This was quite successful, both as an opportunity to gain experience in wikis and as a means of organising their material.  However, the student entries were more in the nature of online articles, with a low level of linkage.  Students were required to hand-in a copy of their wiki material (since this is needed for external examiners) and this perhaps led to the lack of a linked structure.  A more collaborative, group-based approach might be tried to get a larger network but there are obvious problems with attributing authorship.&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;Google docs&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;On one module,the tutors kept a register of attendance.  We opted to use the recently available GoogleSpreadsheets for this, partly to explore the value of collaborative documents.  Technically, this was very successful, and a big improvement on passing Excel  spreadsheets around. However (there seem to be rather a lot of 'however's in this account :-( ) the spreadsheet feels rather cramped and lacks the ability to hold row and column headings in place when scrolling.  (freeze panes)&lt;br /&gt;&lt;br /&gt;RSS&lt;br /&gt;&lt;br /&gt;An advantage of blogs is that they provide an RSS feed which can then be aggregated with other feeds.  (unlike BlackBoard which does not) An attempt was made to use this feed to populate the announcements in Blackboard which was only partly successful, creating an additional point of failure.  Take-up of RSS is still slow but the new myUWE portal  supports RSS feeds so it will be suggested that the blog feed can be added by the individual student.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Podcasts&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A &lt;a href="http://dsa2006.blogspot.com/2006/12/week-10-trees-dom-and-ajax.html"&gt;couple of lectures &lt;/a&gt;were recorded on audio and posted to the blog. I also used Evoca to &lt;a href="http://dsa2006.blogspot.com/2007/01/google-earth.html"&gt;record short messages. &lt;/a&gt;&lt;br /&gt;Whether these initiatives were valued is difficult to say. I think the audio alone is of limited value and integrated slideshow, video and audio is the ideal.  Creating such resources for  small to medium-sized classes, in such as rapidly changing field as the web, may not be economically viable.&lt;br /&gt;&lt;br /&gt;Conclusion&lt;br /&gt;&lt;br /&gt;These new technologies have great promise, but the fit with a corporate culture an institutional E-Learning policy creates tensions.   This year's experiences are certain food for thought.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-6573210582151339072?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/6573210582151339072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=6573210582151339072&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/6573210582151339072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/6573210582151339072'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/06/web-20-in-teaching.html' title='Web 2.0 in teaching'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-7755655313973505696</id><published>2007-06-09T08:16:00.001+01:00</published><updated>2007-06-26T20:37:11.934+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XQuery unit-test'/><title type='text'>XQuery functions</title><content type='html'>Over the last few weeks, I've been writing some general XQuery functions for our own system and in collaboration with &lt;a href="http://www.danmccreary.com/"&gt;Dan McCreary&lt;/a&gt;.  There are XQuery collections to which these could be contributed, notably Priscilla Warmsley's &lt;a href="http://www.xqueryfunctions.com/xq/"&gt;//www.xqueryfunctions.com/xq/&lt;/a&gt;&lt;br /&gt;but some of my functions depend on the eXist function libraries, and I would also like to prove the functions work and show examples of use in unit tests.&lt;br /&gt;&lt;br /&gt;I'm currently working on some system tools to browse the code, develop full coverage tests and help refactor the code for the FOLD application. Part of this suite is an XQuery unit test tool. As an experiment, I've combined the two and put up a simple demo on our public eXist demo server.&lt;br /&gt;&lt;br /&gt;The function is defined in the prolog which  is prepended to each test before execution.  The result can be either text or a node which is compared with the expected result as strings or with deep-equal respectively.&lt;br /&gt;&lt;br /&gt;The test scripts themselves, viewed as XML look a bit of a mess but the source shows the formatting.  CDATA sections are now preserved in stored files  in eXist which is convenient when round-tripping XQuery code containing XML, but is controversial since CDATA is only intended to encode XML characters on input but is not part of the infomodel.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Links &lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.cems.uwe.ac.uk/xmldb/rest//db/CommonCode/index.xql"&gt;CommonCode&lt;/a&gt;&lt;/li&gt;&lt;li&gt;The test script for a &lt;a href="http://www.cems.uwe.ac.uk/xmldb/rest//db/CommonCode/Tests/commas.xml"&gt;function&lt;/a&gt; Dan wrote&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The test script for a &lt;a href="http://www.cems.uwe.ac.uk/xmldb/rest//db/CommonCode/Tests/bandtest2.xml"&gt;BandMap&lt;/a&gt;  structure&lt;/li&gt;&lt;/ul&gt;Next step is to document the test framework itself and provide the means for others to add test scripts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-7755655313973505696?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/7755655313973505696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=7755655313973505696&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/7755655313973505696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/7755655313973505696'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/06/xquery-functions_09.html' title='XQuery functions'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-8669014689944240236</id><published>2007-03-25T17:57:00.000+01:00</published><updated>2007-03-25T18:02:24.285+01:00</updated><title type='text'>SPA2007 - day 0</title><content type='html'>I tinker endlessly with the eXist workshop material, still some solutions to do and the new server isn't having anything to do with the Java Webstart client.  Hopefully it will get fixed before Wednesday afternoon. I'll also have to figure how to create multiple folders with the same initial contents - should be able to use a backup but not sure how to install in a different place.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-8669014689944240236?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/8669014689944240236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=8669014689944240236&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/8669014689944240236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/8669014689944240236'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/03/spa2007-day-0.html' title='SPA2007 - day 0'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-1501734280318661454</id><published>2007-03-19T07:39:00.000Z</published><updated>2007-06-10T10:00:19.692+01:00</updated><title type='text'>FizzBuzz</title><content type='html'>Here's a quick XQuery solution to the FizzBuzz problem posed in &lt;a href="http://www.oreillynet.com/xml/blog/2007/03/fizzbuzz_20_adventures_in_beau.html"&gt;David Patterson's blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I've taken the liberty  of  splitting the hyphenated string into two attributes.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;let $config :=&lt;br /&gt;&amp;lt;fizzbuzz&gt;&lt;br /&gt;&amp;lt;range min="1" max="100"/&gt;&lt;br /&gt;&amp;lt;test&gt;&lt;br /&gt;   &amp;lt;mod value="3" test="0"&gt;Fizz&amp;lt;/mod&gt;&lt;br /&gt;   &amp;lt;mod value="5" test="0"&gt;Buzz&amp;lt;/mod&gt;&lt;br /&gt;&amp;lt;/test&gt;&lt;br /&gt;&amp;lt;/fizzbuzz&gt;&lt;br /&gt;&lt;br /&gt;for $i in ($config/range/@min to $config/range/@max)&lt;br /&gt;let $s :=  for $mod in $config/test/mod&lt;br /&gt;      return&lt;br /&gt;         if ($i mod $mod/@value = $mod/@test)&lt;br /&gt;         then string($mod)&lt;br /&gt;         else ()&lt;br /&gt;return&lt;br /&gt;if (exists($s))&lt;br /&gt;then string-join($s,' ')&lt;br /&gt;else $i&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-1501734280318661454?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/1501734280318661454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=1501734280318661454&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/1501734280318661454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/1501734280318661454'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/03/fizzbuzz.html' title='FizzBuzz'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-6900845670665872841</id><published>2007-03-15T00:06:00.000Z</published><updated>2007-03-19T15:11:08.489Z</updated><title type='text'>Timelines</title><content type='html'>Here are some ways in which timelines are being used in the web:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.timesearch.info/"&gt;TimeSearch&lt;/a&gt;&lt;/li&gt;&lt;li&gt;GoogleEarth &lt;a href="http://www.gearthblog.com/blog/archives/2006/09/google_earth_4_time.html"&gt;timeline&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.hyperhistory.com/online_n2/History_n2/a.html"&gt;HyperHistory&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://simile.mit.edu/timeline/"&gt;SIMILE timeline from MIT&lt;/a&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://simile.mit.edu/timeline/examples/dinosaurs/dinosaurs2.html"&gt;Dinosaur timeline&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Provides a Javascript API to create a complex panning timeline.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Events are uploaded in XML format which defines for each event&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;start title end? isDuration? latestStart? earliestEnd?  image? link? and body&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Cant locate schema for the event stream&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Event date format is not xs:date&lt;/li&gt;&lt;li&gt;body must be a string  i.e. with &amp;lt;  not &lt;&lt;/li&gt;&lt;li&gt;Set the mime type to application/xml&lt;br /&gt;&lt;/li&gt;&lt;li&gt;example &lt;a href="http://simile.mit.edu/timeline/examples/monet/monet.xml"&gt;XML timeline&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;I've implemented the SIMILE timeline in my Family History.  Here is &lt;a href="http://www.cems.uwe.ac.uk/chriswallace/history/code/timeLine.xql?person=Kenneth+Wallace"&gt;an example&lt;/a&gt;&lt;br /&gt;Links to other people load their timelines (although some are incomplete and not working).&lt;br /&gt;&lt;br /&gt;Multiple event streams can be displayed in multiple bands - e.g. here are the lives of &lt;a href="http://www.cems.uwe.ac.uk/chriswallace/history/code/timeLine2.xql?person=Kenneth+Wallace&amp;amp;person=Francis+Wallace"&gt;two family members &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It would be great to get a subset of world history events from TimeSearch to include as a separate band.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;To do:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Convert xs:date to Timeline format&lt;/li&gt;&lt;li&gt;Handle photos with missing dates&lt;/li&gt;&lt;li&gt;Focus timeline when no date of birth&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-6900845670665872841?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/6900845670665872841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=6900845670665872841&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/6900845670665872841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/6900845670665872841'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/03/timelines.html' title='Timelines'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-6525895807795945452</id><published>2007-03-14T23:52:00.000Z</published><updated>2007-03-15T00:00:58.959Z</updated><title type='text'>My Family History</title><content type='html'>Bamber Gascoigne's TimeSearch got me thinking about my family history project again.&lt;br /&gt;&lt;br /&gt;The Family History project started with the idea of putting some family photos on the web, together with some meta data about the photo. Most had a list of subjects but only very occassionally a date. I had the idea that if the birth dates of the subjects were added, and the age of just one subject could be guessed, the system could infer the date of the photograph, and hence the age of all subjects. With birth and death data included, a timeline could be extracted for a person, including birth, deaths and marriages, photographs and even world events.&lt;br /&gt;&lt;br /&gt;The resultant eXist/XQuery/XSLT prototype is &lt;a href="http://www.cems.uwe.ac.uk/chriswallace/history/index.xml"&gt;here.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;What would be nice would be be able to combine such personal histories with events in world history, or to compare the timelines for famous people with that of a family member. A simplistic approach would be to deep link into history sites and this is what the prototype has done, creating links like&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.timesearch.info/default.asp?getyear=1946&amp;conid=2"&gt;TimeSearch 1946&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/1946"&gt;Wikipedia 1946&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;These generated links are not as clever as those in TimeSearch, which I would guess are hand edited.&lt;br /&gt;&lt;br /&gt;This is simple to accomplish, but its rather one-side - my site can link to another, but it can't mashup the data with my own. A mashup requires an API and a published format for exported content.  I suppose we might look at &lt;a href="http://microformats.org/wiki/hcalendar"&gt;hcalendar &lt;/a&gt;as one possible format but it would need  extending it to support tags.  RSS is another possibility.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-6525895807795945452?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/6525895807795945452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=6525895807795945452&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/6525895807795945452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/6525895807795945452'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/03/my-family-history.html' title='My Family History'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-5157454701380472118</id><published>2007-03-14T17:09:00.000Z</published><updated>2007-03-15T00:22:53.604Z</updated><title type='text'>TimeSearch by Bamber Gascoigne</title><content type='html'>The item on the BBC's Start the Week' by &lt;a href="http://en.wikipedia.org/wiki/Bamber_Gascoigne"&gt;Bamber Gascoigne&lt;/a&gt; on the history site he has created called &lt;a href="http://www.timesearch.info/"&gt;TimeSearch&lt;/a&gt; sparked my interest  TimeSearch is a history search portal, using event stubs to provide links onwards to a wide range of sites - from general news sites, Wikipedia and Google images to specialist on-line resources. Events can be selected using two hierarchical category systems,  location and them as well as year. I confess I had some trouble deselecting categories once selected.&lt;br /&gt;&lt;br /&gt;This is the latest form of delivery of the extensive material Bamber has created and put on line in:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.historyworld.net/"&gt;History World&lt;/a&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;An online encyclopedia of history with great little quizes.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href="http://www.oceanindex.net/"&gt;OCEAN index&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;One wonders how this authored material compares with the collaborative Wikipedia. It is certainly an impressive and rich resource.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-5157454701380472118?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/5157454701380472118/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=5157454701380472118&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/5157454701380472118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/5157454701380472118'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/03/events-and-timelines.html' title='TimeSearch by Bamber Gascoigne'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-4552977920144701508</id><published>2007-02-13T22:32:00.000Z</published><updated>2007-02-15T14:48:26.246Z</updated><title type='text'>SPA 2007</title><content type='html'>I have been working on my session for this year's SPA for a while now.   Seems a timely session to run according to Elliotte Rusty Harold's  &lt;a href="http://www-128.ibm.com/developerworks/xml/library/x-xml2007predictions.html"&gt;predictions&lt;/a&gt;  for XML in 2007 (which mentions eXist).&lt;br /&gt;&lt;br /&gt;Mostly I have been vacillating about which case study to use - I have so many part-finished projects.  At first I revived the &lt;a href="http://thewallaceline.blogspot.com/2007/01/whisky-laphroaig.html"&gt;Whisky project&lt;/a&gt;, but after a lot of work, this felt like a bit of a slog - it was good as a modeling exercise but didn't reveal the power of XML and XQuery to my satisfaction.  I then switched to the Bus Timetable project, which is much more realistic and one which I want to solve to replace the existing PHP/MySQL application with its hand-crafted timetables.  However the data here is very complex, and the data files I have so far are incomplete.  Nevertheless, this is the case study I settled on, although I did a short detour into the &lt;a href="http://thewallaceline.blogspot.com/2006/10/declarative-processes.html"&gt;DVD hire example &lt;/a&gt;and of course there is always &lt;a href="http://www.cems.uwe.ac.uk/exist/index.xql"&gt;StudentsOnline&lt;/a&gt;, the main site we are developing with this technology.&lt;br /&gt;&lt;br /&gt;Timetables come from TravelLine South-West in the form of TransXChange files.  These first need processing to a more amenable structure. The actual data model is highly interlinked which makes for some XPath fun.  Conversion is required to calculate absolute times (TXC has time differences between stops)  and to convert from OS Easting and Northing to Lat/Long .  With the simplified structures, I can present the data in various ways.  HTML pages show the stops and the departures times but the neat idea is to generate kml files to overlay on Google Earth.  Using a NetworkLink, I  can display changing times  on the map. The XPath date and time functions are a great help.&lt;br /&gt;&lt;br /&gt;Other bits of functionality include an Ajaxian incremental Bus stop locator and membership registration rretainig favourite stops and services. &lt;br /&gt;&lt;br /&gt;Here are some useful links for this project:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;eXist database &lt;a href="http://exist-db.org/"&gt;home&lt;/a&gt;&lt;/li&gt;&lt;li&gt;an XQuery tutorial from &lt;a href="http://www-128.ibm.com/developerworks/xml/library/x-xquery.html"&gt;Howard Katz&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;A basic Timetable implementation (pending)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.transxchange.org.uk/"&gt;TransXChange&lt;/a&gt; documentation&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.travelinesw.com/"&gt;TravelLine South West&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://earth.google.com/"&gt;Google Earth&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://earth.google.com/kml/"&gt;kml&lt;/a&gt; description and reference&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-4552977920144701508?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/4552977920144701508/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=4552977920144701508&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/4552977920144701508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/4552977920144701508'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/02/spa-2007.html' title='SPA 2007'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-2289955515524120750</id><published>2007-01-29T14:02:00.000Z</published><updated>2007-03-15T00:07:34.537Z</updated><title type='text'>Computed synethesia</title><content type='html'>The Cloud appreciation society lead me to the &lt;a href="http://cloudharp.org/"&gt;Cloud Harp project&lt;/a&gt;. I'm listening to a recording made in 2004 - very ethereal.&lt;br /&gt;&lt;br /&gt;It re-generates my interest in artificial synaesthesia generally and perhaps a return to my Bristol Harbour project, using image stream and image processing to pick out the frequency and direction of wave patterns to modulate music, with self-contained stations set up around the harbour.&lt;br /&gt;&lt;br /&gt;Information arts often has artificial synaesthesia at its heart, converting information in one medium to information in another, with the aim of thus enhancing our appreciation and understanding of the source domain and creating beauty and interest in the target domain.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-2289955515524120750?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/2289955515524120750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=2289955515524120750&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/2289955515524120750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/2289955515524120750'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/01/computed-synethesia.html' title='Computed synethesia'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-8803005709236603440</id><published>2007-01-28T19:01:00.000Z</published><updated>2007-01-28T20:22:02.500Z</updated><title type='text'>Cloud Appreciation Society</title><content type='html'>One of my Christmas presents was  'The Cloudspotter's Guide' by Gavin Pretor-Pinney and published in 2006 by Hodder &amp; Stoughton  on behalf of the &lt;a href="http://www.cloudappreciationsociety.org/"&gt;cloud appreciation society&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This site includes an excellent example of a subject-specific photo site, with many excellent photographs of cloud formations, optical effects and associated phenomena. The site was interesting in the context of the &lt;a href="http://dsa2006.blogspot.com/"&gt;DSA module&lt;/a&gt; because it combines the problem of creating a photo site with the problems of tagging and categorising information, so I thought I'd write a review of it here, as perhaps as an example of what might have been included in theFlickr review.  Next year I think I will base the coursework on a selection of sites like this rather than a monster site like Flickr.  I welcome suggestions.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Navigation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The home page is a page featuring the last photo to be loaded.&lt;br /&gt;&lt;br /&gt;Search by category and by partial string match within the title string are provided on this page. These lead to two different album pages - a paged layout in the case of the category, a list with thumbnails and titles in front of the page from which the search was launched in the case of the title search. Its not clear why there should be two different approaches. Usefully, the category selector shows the number of photographs in that category.&lt;br /&gt;&lt;br /&gt;Direct links to the categories to which the current image has been assigned are provided and a featured category (Cloud Lookalikes) is at the top.&lt;br /&gt;&lt;br /&gt;Each page includes a selection of other photographs. The criteria appears to be just the adjacent photo accession numbers and is not based on any criteria of similarity, but nevertheless it does encourage serendipitous browsing. Curiously the aspect ratio of these photos is determined by that of the main photo, leading to mal-shaped images.&lt;br /&gt;&lt;br /&gt;Clicking on the photo rather surprisingly links to the next photo in sequence. There is also a 'Previous Page' link which is functionally a back button - it is not quite clear why this is included since this is a standard browser button. Perhaps Next and Previous links (in the accession sequence) would provide a better navigational mechanism.&lt;br /&gt;&lt;br /&gt;A search (or link) to a members photos would be useful.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Photo Data&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Images are jpegs at medium and thumbnail resolution.&lt;br /&gt;&lt;br /&gt;Meta data include the name of the copyright owner (or is it just the member?), a descriptive title, data and time (but of upload I would guess, not of the photograph itself). The title can contain links e.g. to related sites.&lt;br /&gt;&lt;br /&gt;Each photograph is related to several categories.&lt;br /&gt;&lt;br /&gt;It is a pity that the photographs do not appear to be geo-coded, because it would be nice to mash these up with Google Earth. There is often a description of the place which could be translated through a geo-coding service.  Since some photos are taken from planes, altitude data is needed too.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Tagging and classification&lt;/span&gt;&lt;br /&gt;Each photograph is classified into one or several of around 40 categories and hence linked to other photos in the same category through that category. The category system itself is interesting as a information construct. On the surface, it would seem that it would benefit from some hierarchy. e.g.&lt;br /&gt;&lt;br /&gt;* All photos&lt;br /&gt;** Cloud Type&lt;br /&gt;*** Cumulus&lt;br /&gt;**** Kelvin-Helmholtz wave cloud&lt;br /&gt;***&lt;br /&gt;** Cloud features&lt;br /&gt;*** Contrails&lt;br /&gt;***&lt;br /&gt;** Time-of-Day&lt;br /&gt;*** Sunrise&lt;br /&gt;*** Sunset&lt;br /&gt;** Optical Effects&lt;br /&gt;*** Rainbow&lt;br /&gt;*** Halo&lt;br /&gt;***&lt;br /&gt;and probably others.&lt;br /&gt;&lt;br /&gt;It also seems that some category meta-data is embedded in the name - the numbers on Cloud types is a reference to the Chapters in the book. Clearly a general description of the category itself could also be part of the overall data structure. The book provides a hierarchical classification of cloud types which would be useful to include. There are also occasional synonyms embedded in the name -eg Mamma (also know as mammatus) which could be treated uniformly as category meta-data.&lt;br /&gt;&lt;br /&gt;The task of classifying each photo into these categories is not open to the public or members but is seen as an expert task. However there are places, such as in the category of 'Clouds that look like things' where folksomony would seem to be appropriate. Photographs also sometimes contain objects e.g. balloons, planes, boats for which arbitrary tags seem suitable.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Upload&lt;/span&gt;&lt;br /&gt;Rather surprisingly, photo upload, even by members, is not supported, and photos have to be emailed to the webmaster with accompanying meta data for upload and categorisation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Rating and comments&lt;/span&gt;&lt;br /&gt;The public  can easily rate photos and add comments.  The comments are generally expressions of appreciation of no interest to anyone but the photographer. There is no information on the basis of the rating - indeed all photos I've seen are rated 4.It is not clear what value this adds or indeed what is being rated - the photograph or the subject.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Compatibility and Accessibility&lt;/span&gt;&lt;br /&gt;Images have alt tags but these are the copyright names, not the description of the image which would better aid the reader.&lt;br /&gt;&lt;br /&gt;There are keywords in the page meta data but these are not photo specific.&lt;br /&gt;&lt;br /&gt;XHTML compliance - main photo page shows 1 error and 17 warnings. Typically these are problems with table and div tag nesting and problems with &amp;amp; . The error is a non-HTML tag.&lt;br /&gt;&lt;br /&gt;The display of some characters in the title is broken (on Firefox and IE) e.g &lt;a href="http://cloudappreciationsociety.org/gallery/index.php?showimage=620"&gt;this&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;API and Feeds&lt;/span&gt;&lt;br /&gt;The site provides RSS2.0  and Atom feeds of the latest photo additions and a Feedburner link.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Technology&lt;/span&gt;&lt;br /&gt;The scripting language is PHP, images are held as files, not held in the database. Not sure what database is used (probably MySQL?).  CSS is used for styling. Small amount of Javascript e.g. for GIF rollover on the rating buttons and call to update the rating. One function is defined (flip) which is not used.&lt;br /&gt;&lt;br /&gt;The program architecture uses a single index.php script with a parameter to determine what page type to return, rather than multiple scripts.  Interesting design issue here.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Data Model&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_19XcwSkLYrk/Rbz6FPbT1cI/AAAAAAAAAAY/PbgPTLC6qf0/s1600-h/clouder.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_19XcwSkLYrk/Rbz6FPbT1cI/AAAAAAAAAAY/PbgPTLC6qf0/s320/clouder.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5025166252185998786" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-8803005709236603440?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/8803005709236603440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=8803005709236603440&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/8803005709236603440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/8803005709236603440'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/01/cloud-appreciation-society_28.html' title='Cloud Appreciation Society'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_19XcwSkLYrk/Rbz6FPbT1cI/AAAAAAAAAAY/PbgPTLC6qf0/s72-c/clouder.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-5878826172480267805</id><published>2007-01-20T18:18:00.000Z</published><updated>2007-01-20T18:45:43.030Z</updated><title type='text'>Where I've been</title><content type='html'>Just discovered this little application which generates a GIF map of the world showing the countries you have visited.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://douweosinga.com/projects/visitedcountries"&gt;&lt;img src="http://www.world66.com/community/mymaps/worldmap?visited=CAUSAGBBDMGPGDMQPALCVCTTVEDZCVEGERMATNQICZFRDEGIGRIEITLILUMTMCNLPTRUESCHUKVAJOOMTRYECNINIDMYMVMNSGLKTHAUCKFJPFNZNUPNCKTO" width="400"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So many places yet to see, and so much of places visited unseen like most of the States: &lt;br /&gt;&lt;br /&gt;&lt;a href="http://douweosinga.com/projects/visitedstates"&gt;&lt;img src="http://www.world66.com/myworld66/visitedStates/statemap?visited=CAMNNJNYWI" width="400"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;From &lt;a href="http://douweosinga.com/projects"&gt;Douwe Osinga&lt;/a&gt;, a Google engineer&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-5878826172480267805?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/5878826172480267805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=5878826172480267805&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/5878826172480267805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/5878826172480267805'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/01/where-ive-been.html' title='Where I&apos;ve been'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-7992696531617975727</id><published>2007-01-18T18:12:00.000Z</published><updated>2007-01-18T18:52:12.628Z</updated><title type='text'>Voice snippets</title><content type='html'>I've been experimenting today with  &lt;a href="http://www.evoca.com/"&gt;http://www.evoca.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A free account allows you to record and store up to 60 minutes of sound.  This interface is simple to use.  Sound can be captured from a number of sources but the easiest is directly from a microphone on the computer.  Everything is done through the web interface.  When the recording has been made, an HTML snippet is provided to paste where you need it, and this invokes a flash player.&lt;br /&gt;&lt;br /&gt;I'm trying these as an addition to my blog for the &lt;a href="http://dsa2006.blogspot.com/2007/01/google-earth.html"&gt;DSA module&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I suppose it will just pollute the airwaves, but maybe it offers another mode for information dissemination which may just help some students.  For two lectures last year I recorded the whole lecture and mounted it as an MP3 file, but they very long and un-synchronised   with the Powerpoint slides.  I tried calling out slide numbers but it was reminiscent of the early soccer commentaries which used numbered squares (the origin I  learnt today of the phrase 'back to square 1') .&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-7992696531617975727?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/7992696531617975727/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=7992696531617975727&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/7992696531617975727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/7992696531617975727'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/01/voice-snippets.html' title='Voice snippets'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-318435586250683314</id><published>2007-01-15T18:08:00.001Z</published><updated>2007-01-18T18:11:55.679Z</updated><title type='text'>Whisky - Laphroaig</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-size:85%;"&gt;This entry is a sample of data sources on a specific whisky - assembled here as a notepad for the workshop at SPA2007 and for the Data, Schemas and Applications module.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Laphroaig&lt;br /&gt;&lt;/span&gt;Laphroaig Distillery,&lt;br /&gt;Port Ellen,&lt;br /&gt;Isle of Islay,&lt;br /&gt;Argyll,&lt;br /&gt;PA42 7DU  Tel. 01496 302418&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.laphroaig.com/"&gt;Home site&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;General&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://www.scotlandwhisky.com/distilleries/islay/Laphroaig"&gt;Scotland: Whiskies and Distilleries&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Laphroaig"&gt;Wikipedia&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://www.scotchwhisky.net/distilleries/laphroig.htm"&gt;&lt;/a&gt;&lt;a href="http://www.scotchwhisky.net/distilleries/laphroig.htm"&gt;ScotchWhisky.net&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://www.whiskymag.com/directory/detail/laphroaig_distillery.6067.html"&gt;Whisky Magazine&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://www.scotlandwhisky.com/distilleries/islay/Laphroaig"&gt;Scotland Whisky&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:85%;"&gt;John Butler's &lt;a href="http://www.dcs.ed.ac.uk/home/jhb/whisky/"&gt;site&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;Types of information&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.laphroaig.com/history/chronology/index.asp?expanded=our_history.chronology"&gt;Chronology&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Location&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Gooogle Map &lt;span style="font-size:130%;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://maps.google.com/maps?q=PA42%207DU"&gt;http://maps.google.com/maps?q=PA42%207DU&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:85%;"&gt;Multimap &lt;a href="http://www.multimap.com/map/browse.cgi?pc=PA427DU&amp;scale=25000&amp;amp;cat=loc"&gt;http://www.multimap.com/map/browse.cgi?pc=PA427DU&amp;scale=25000&amp;amp;cat=loc&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:85%;"&gt;Wikipedia &lt;a href="http://tools.wikimedia.de/%7Emagnus/geo/geohack.php?params=55_37_55_N_06_08_58_W_type:landmark"&gt;Geohack&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:85%;"&gt;Pronunication  - &lt;a href="http://www.dcs.ed.ac.uk/home/jhb/whisky/smws/29.html"&gt;John Butler's site&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:85%;"&gt;Taste &lt;a href="http://www.whiskyclassified.com/laphroaig.html"&gt;http://www.whiskyclassified.com/laphroaig.html&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:85%;"&gt;Tasting notes e.g&lt;a href="http://www.dcs.ed.ac.uk/home/jhb/whisky/padlip.html"&gt;. Mike Padlipsky&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:85%;"&gt;Ownership  - changing ownership - see the yearbook&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:85%;"&gt;Bottlings &lt;a href="http://www.laphroaig.com/whiskies/index.asp?expanded=our_whiskies"&gt; http://www.laphroaig.com/whiskies/index.asp?expanded=our_whiskies&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:85%;"&gt;Glossary &lt;a href="http://www.whiskymag.com/words/"&gt;http://www.whiskymag.com/words/&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Printed&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Malt Whisky Yearbook 2006 p170&lt;/li&gt;&lt;li&gt;Collins Gem Whisky p 171&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-318435586250683314?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/318435586250683314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=318435586250683314&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/318435586250683314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/318435586250683314'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/01/whisky-laphroaig.html' title='Whisky - Laphroaig'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-3903136982659994651</id><published>2007-01-15T10:54:00.000Z</published><updated>2007-01-17T22:39:01.962Z</updated><title type='text'>Beyond Belief</title><content type='html'>I spent part of this weekend listening to the presentations at &lt;a href="http://beyondbelief2006.org/"&gt;BeyondBelief2006  &lt;/a&gt;for which all sessions over the two and a half days are available as Flash video.  A great resource to have provided and very well done.  Ongoing discussion on the &lt;a href="http://www.edge.org/discourse/bb.html"&gt;Edge.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Amongst the speakers, I was particularly taken with&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Carolyn Porco - the &lt;a href="http://antwrp.gsfc.nasa.gov/apod/ap061016.html"&gt;picture &lt;/a&gt;of Earth through the back-lit rings of Saturn is just wonderful.&lt;/li&gt;&lt;li&gt;Harold Kroto  - &lt;a href="http://www.vega.org.uk/"&gt;vega science trust&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Mahzarin Banaji   - &lt;a href="https://implicit.harvard.edu/implicit/"&gt;Implicit association tests&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Ann Druyan - &lt;a href="http://www.carlsagan.com/"&gt;Carl Sagan&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Amongst other thoughts provoked by these sessions, I was struck by the observation that it is scientists of all breeds who are most directly trying to understand and pay attention to 'God', whilst the religous and the theologians pay attention to the works of man - the books, the practices, the historical development of religous thought by man.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-3903136982659994651?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/3903136982659994651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=3903136982659994651&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/3903136982659994651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/3903136982659994651'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2007/01/beyond-belief.html' title='Beyond Belief'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-116268037902102354</id><published>2006-11-04T22:45:00.000Z</published><updated>2006-11-04T22:46:19.033Z</updated><title type='text'>Double line spacing in Dissertations</title><content type='html'>It is standard practice to require dissertations to be double-spaced. In the age of word processors, one wonders why this practice persists. This must surely be a legacy from the days when dissertations were typewritten and students were allowed to make corrections in situ rather than re-print. Word processors have eliminated that problem. Double-spacing might also be suitable for drafts which require annotation for editing, but final copies of dissertations are not used in this way and modern techniques such as commenting do this job.&lt;br /&gt;&lt;br /&gt;(Primo Levi's 'Chromium' in 'The Periodic Table' has several great examples of the way solutions to old probelms hang around even when the problem not longer exists.)&lt;br /&gt;&lt;br /&gt;I have seen readability expressed as another reason for double-spacing.  It's not easy to track down the evidence for this.  &lt;a href="http://www.psych.utoronto.ca/%7Emuter/Abs1984b.htm"&gt;Kruk and Muter(1984)&lt;/a&gt; report "single spacing produced reading that was 10.9% slower than that produced by double spacing" on a 'video' screen.  &lt;a href="http://psychology.wichita.edu/surl/usabilitynews/62/density.htm"&gt;Weller&lt;/a&gt; (2004) reports on a previous study that "It was discovered that single spacing of text requires more eye fixations per line and therefore fewer words are read per fixation, which increases reading time (Kohler, Duchnicky &amp;amp; Ferguson, 1981)." But Mills and Weldon (1987) report that this same study showed a 2% slowing of reading rate, hardly convicing evidence.&lt;br /&gt;&lt;br /&gt;Other writers express the view that this convention is out-moded e.g. the author of the Tex manual : &lt;a href="http://www.tex.ac.uk/cgi-bin/texfaq2html?label=linespace"&gt; link&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.princeton.edu/%7Emudd/thesis/general.html"&gt;Princeton&lt;/a&gt; University now accepts single-spaced printed copies although ProQuest (an online dissertation repository) still requires double-spacing for the electronic copy ( and hence all printed copies therefrom). It is claimed that this improved on-line readability.&lt;br /&gt;&lt;br /&gt;A &lt;a href="http://another-brilliant-idea.blogspot.com/2006/06/single-spaced-dissertation.html"&gt;PhD Student &lt;/a&gt;in the US has calculated that 20,000 reams of paper would be saved if ProQuest accepted single-spaced.&lt;br /&gt;&lt;br /&gt;Double-spacing is often mandated  in legal practice but even here the convention is &lt;a href="http://www.utexas.edu/law/faculty/wschiess/legalwriting/2006/03/document-design-double-spacing.html"&gt;challenged.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-116268037902102354?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/116268037902102354/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=116268037902102354&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/116268037902102354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/116268037902102354'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2006/11/double-line-spacing-in-dissertations.html' title='Double line spacing in Dissertations'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-116159189420131862</id><published>2006-10-23T09:11:00.000+01:00</published><updated>2006-10-23T23:37:04.980+01:00</updated><title type='text'>Declarative Processes</title><content type='html'>I am  getting back to the declarative process work I began a couple of years ago.   Peter Marks and Ben Moseley's session at SPA2006 got me started again.&lt;br /&gt;&lt;br /&gt;I now have a partial &lt;a href="http://www.cems.uwe.ac.uk/chriswallace/dvd3/index.xql"&gt; implementation&lt;/a&gt; of a DVD rental application written in a declarative process style using eXist and XQuery.  The essence of the design is to retain all events and compute the current state by the evaluation of predicates over the event trace.  The rules are hard-coded in eXist functions in this demo.  Rules are mostly XPath expressions.  For example&lt;br /&gt;&lt;ul&gt;&lt;li&gt;To find the current address  for a person $p given SetAddress events&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li style="font-family: courier new;"&gt;events($p)[SetAddress][last()]//address&lt;/li&gt;&lt;/ul&gt;&lt;li style="font-family: courier new;"&gt;To find the address at $date&lt;/li&gt;&lt;ul&gt;&lt;li style="font-family: courier new;"&gt;events($p)[SetAddress][@date &lt; $date][last()]//address&lt;/li&gt;&lt;/ul&gt;&lt;li style="font-family: courier new;"&gt;To check if a member is suspended given Suspend and Reinstate events&lt;/li&gt;&lt;ul&gt;&lt;li style="font-family: courier new;"&gt;exists( events($p)[Suspend or Reinstate][last()][Suspend])&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;Some of the advantages of this approach are clear:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;the state of the system can be evaluated at any time in the past by filtering the event stream for events before the specified date&lt;/li&gt;&lt;li&gt;if the rules are held as data, the state can be computed  synoptically (i.e. according to rules applicable at the time) - but how  should they be encoded  - as executable XQuery expressions?&lt;/li&gt;&lt;li&gt;changes in rules are supported, allowing re-interpretation of the past&lt;/li&gt;&lt;li&gt;subjective rules are supported although only within the event language created&lt;/li&gt;&lt;li&gt;'what-if' analysis is supported, allowing questions to be asked about the impact of changes in the rules&lt;br /&gt;&lt;/li&gt;&lt;li&gt;rules are robust to insertion of other events&lt;/li&gt;&lt;li&gt;the event history is often required to understand what has happened and why so there is no addition storage requirement&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Some disadvantages are also clear:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The computational cost is higher than simply fetching  a simple value&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Writing declarative rules is not easy and will need a higher level language&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The approach requires  a global model of the system,  so its applicable to systems but not to distributed systems&lt;/li&gt;&lt;li&gt;It's not yet clear what range of behaviour is  expressable&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Much more work is needed to see how well this model will fit with other processes.  Some applications include:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;lightweight processes - e.g. academic processes such as setting and marking coursework&lt;br /&gt;&lt;/li&gt;&lt;li&gt;descriptive models of real processes and their subsequent analysis for process improvement&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:130%;"&gt;Prior work&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;The &lt;a href="http://alloy.mit.edu"&gt;Alloy language&lt;/a&gt; (Daniel Jackson, MIT) &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Peter Marks and Ben Moseley - &lt;a href="http://www.spaconference.org/cgi-bin/wiki.pl/?FunctionalRelationalProgramming"&gt;Functional Relational Programming&lt;/a&gt;, SPA 2007, &lt;a href="http://web.mac.com/ben_moseley/frp/frp.html"&gt;FRP site&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Work on rule-based language has had a rough ride - several projects in this area (e.g. BRML) are defunct.  Some activity in &lt;a href="http://oxygen.informatik.tu-cottbus.de/rewerse-i1/?q=node/6"&gt;R2ML &lt;/a&gt;and &lt;a href="http://www.ruleml.org/"&gt;RuleML.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://xml.coverpages.org/brml.html"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-116159189420131862?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/116159189420131862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=116159189420131862&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/116159189420131862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/116159189420131862'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2006/10/declarative-processes.html' title='Declarative Processes'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-115471852927169515</id><published>2006-08-04T20:07:00.000+01:00</published><updated>2006-10-24T00:09:11.496+01:00</updated><title type='text'>America</title><content type='html'>Time to forget about University and the project. Tomorrow we're off to the USA for adventure and catching up with friends and relatives.&lt;br /&gt;&lt;br /&gt;Here is a link to a GoogleEarth overlay containing the main places we are visiting:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://cems.stikipad.com/attachment/asset/7770/Chris_and_Julia_s_America_trip.kmz"&gt;Trip on Google Earth&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Photos from the Minnesota trip are now up on Flickr:  &lt;a href="http://www.flickr.com/photos/paddlers9/"&gt;http://www.flickr.com/photos/paddlers9/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-115471852927169515?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/115471852927169515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=115471852927169515&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/115471852927169515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/115471852927169515'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2006/08/america.html' title='America'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-114941043706743582</id><published>2006-06-04T09:06:00.000+01:00</published><updated>2006-06-04T09:56:35.796+01:00</updated><title type='text'>eXist  examples</title><content type='html'>I now have somewhere to host my example XML database examples.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cems.uwe.ac.uk/chriswallace/index.xql"&gt;http://www.cems.uwe.ac.uk/chriswallace/index.xql&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This supercedes the previous hosts for my teaching applications on a friend's  server and on the exist-db demo server. &lt;br /&gt;&lt;br /&gt;There are a few there, but further development will have to wait till the end of the term. Few typos I've just spotted :- (&lt;br /&gt;&lt;br /&gt;One problem I faced was  to allow a visitor to view the Xquery files themselves.  I initially saw this as a eXist problem, needing an eXist solution, and indeed Adam, one of the eXist developers, put in a feature to support this.  However I slowly realised that if I wanted to put up a number of examples (there are about 9 in various stages of development) , I should develop a schema for an application index page, and individual XML configuration files instead of writing unique pages.   I can then use XSLT to display the page.  If I then wrote an Xquery to fetch a query and display it , I could use the application configuration XML to authorise access to the scripts.&lt;br /&gt;&lt;br /&gt;This experience prompted or reminded me of a couple of computing adages:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The only numbers of importance in computing are 1, 2 and many- with its meta counting variant:   1, 2, Schema &lt;/li&gt;&lt;li&gt;Use of the configuration file to generate the web page and to authorise access to the script as an example of the Shanley principle - in which one component serves multiple purposes  see Michael  Jackson, &lt;span style="font-style: italic;"&gt;Software Requirements and Specifications&lt;/span&gt;, Addison-Wesley 1995, p29-30].&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;In future, I want to enhance this configuration file to be a description of the application architecture and information flow, so I can also generate, via GraphViz, a clickable SVG image of the application.&lt;br /&gt;&lt;br /&gt;That's the problem with eXist and XQuery: this technology greatly reduces the time needed to create an application, but it increases the range of ideas for applicatins which can be easily implemented even more!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-114941043706743582?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/114941043706743582/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=114941043706743582&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/114941043706743582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/114941043706743582'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2006/06/exist-examples.html' title='eXist  examples'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-114224968200915129</id><published>2006-03-13T11:22:00.000Z</published><updated>2006-03-14T05:42:35.046Z</updated><title type='text'>RSS</title><content type='html'>Discovered &lt;a href="http://backstage.bbc.co.uk/"&gt;bbc backstage &lt;/a&gt;this morning whilst researching for my lecture on Web services and REST.  As an experiment, I thought I'd add a page of RSS-derived links to the FOLD.  I shouldn't still be surprised by this, but it only took a few lines to add a primitive page.&lt;br /&gt;&lt;br /&gt;I've put &lt;a href="http://demo.exist-db.org/servlet//db/chriswallace/bbcnews/index.xql"&gt;the demo &lt;/a&gt;up on the exist demo site.  There is also a version which generates Voice+XML to make a real newsreader. It needs Opera 8 with the speech extension and there is only a selection of two American voices but it handles the task very well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-114224968200915129?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/114224968200915129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=114224968200915129&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/114224968200915129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/114224968200915129'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2006/03/rss.html' title='RSS'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-114162740527876102</id><published>2006-03-06T06:25:00.000Z</published><updated>2006-03-06T19:11:50.086Z</updated><title type='text'>Cellular automata and Processing</title><content type='html'>I've just re-discovered my &lt;a href="http://processing.org/"&gt;Processing&lt;/a&gt; application which implements the generalised Conway Game of Life.  The interface allows you to set any rule - for each of the counts of alive neighbours, whether a dead cell lives or a live cell dies.  You can also run Conway's rule or generate a random rule.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cems.uwe.ac.uk/%7Ecjwallac/tools/processing/randomlife.php"&gt;Here it is&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;and here is my &lt;a href="http://www.cems.uwe.ac.uk/%7Ecjwallac/tools/processing/"&gt;Processing page&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;What it doesnt have is any way to register interesting rules the viewer may discover.  I discovered a nice one today: l2d=134&amp;d2l=157  which shows constantly varying interesting behaviour - perhaps for a screen saver.  Also l2d=125&amp;amp;amp;d2l=3568&amp;id=0.1 which is a slow converger to nearly all white with a few blinkers.&lt;br /&gt;&lt;br /&gt;So two jobs to do:  One to allow finds to be registered and commented on, the other to take automata specification from the URL in a form like that above.  Both seem very Web2.0 - the first enabling participation, the second a unique url for every resource.&lt;br /&gt;&lt;br /&gt;Apart from being a exercise in writing Processing, I use it in a lecture on Processes and Emergence.&lt;br /&gt;&lt;br /&gt;'Processing'  is a poor brand name (try searching for it!)  [like eXist  in that regard] but a wonderful little language for animations.  Developed by two design students form MIT, Ben Fry and Casey Reas, it is open-source software with a really nice little IDE, Java-based (it generates a Java applet) with  some great examples of both animations and information display.  A much better introduction to programming than full-on Java I think and a candidate for a first language, partly because it places emphasis on algorithms and change, not structure and stasis.  Its also much simpler than Flash Actionscript as well as non-propriatory.&lt;br /&gt;&lt;br /&gt;Here are some  of my favourite Processing examples&lt;br /&gt;&lt;br /&gt;&lt;a href="http://acg.media.mit.edu/people/fry/zipdecode/"&gt;Zipcodes&lt;/a&gt; by Ben Fry  - locates a US Zipcode&lt;br /&gt;&lt;a href="http://www.aaronkoblin.com/work/faa/"&gt;Flight Patterns&lt;/a&gt; by Aaron Goblin - visualising the flights of planes in the US on a single day&lt;br /&gt;&lt;a href="http://www.solaas.com.ar/dreamlines/"&gt;Dreamlines&lt;/a&gt; by  Leonardo Solaas - a Flickr/Processing mash-up&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-114162740527876102?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/114162740527876102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=114162740527876102&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/114162740527876102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/114162740527876102'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2006/03/cellular-automata-and-processing.html' title='Cellular automata and Processing'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-113964235808005469</id><published>2006-02-11T07:05:00.000Z</published><updated>2007-03-14T23:42:33.101Z</updated><title type='text'>Family Relationships</title><content type='html'>The family album site really needs generalized deduction.  The deductions about dates and ages are hand coded:&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;deduce the date of the photo:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;photo.deduceddate =&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      (photo.date,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;       { some subject s | s.birthday  and photo.s.age | s.birthday + photo.s.age},&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;      )[1]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;deduce the age of the subjects&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;     all s: subject |&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;            s.deducedage = (photo.s.age, photo.deduceddate + s.deducedage)[1]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One  neat trick would be to calculate relative relationships:  if the viewer is x and the subject is s then what is s to x ( great great grand uncle or even the more verbose -  your father's father's father's brother) &lt;br /&gt;&lt;br /&gt;This calls for a Prolog engine perhaps&lt;br /&gt;&lt;br /&gt;Possibilities include&lt;br /&gt; &lt;ul&gt;&lt;li&gt;&lt;a href="http://christophe.delord.free.fr/en/pylog/"&gt;PyLog&lt;/a&gt; a Prolog translater for Python&lt;/li&gt;&lt;li&gt;  A number of Prolog engines listed&lt;a href="http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/prolog/prg/part2/faq-doc-2.html"&gt; here&lt;/a&gt; but this looks very old.&lt;/li&gt;&lt;/ul&gt;Or RDF and Jena?&lt;br /&gt;[sites which are undated are just terrible - I must remember that on my own site]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-113964235808005469?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/113964235808005469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=113964235808005469&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/113964235808005469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/113964235808005469'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2006/02/family-relationships.html' title='Family Relationships'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-113913445636096524</id><published>2006-02-05T09:58:00.000Z</published><updated>2006-02-11T07:03:13.270Z</updated><title type='text'>Exist NDX web server</title><content type='html'>Paul  has generously provided me with space on his server to install exist in its Jetty configuration.  This provides me with an external site which I can use with GoogleMaps. So far I've been putting up the &lt;a href="http://www.herosofascalon.org.uk:8080/exist/servlet/db/history/index.xql"&gt;family history site.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Developing on this site is much more immediate that with my typical FTP enabled site.  With the Java client, I can work directly on the database , editing code, uploading scripts and photos and executing test queries.  There is also a rather safer web interface. Great for rapid development. I  was working on improving the XSLT and looking at the problem of aliases (maiden names usually) .  I'm so used to using the oh-so-useful generalised = in Xquery that I forgot that Xalan is still on XSLT 1.0 with XPath 1.0, whereas XQuery uses XPath 2.0.  This generalisation is the main difference to hit me but its so useful and a pain to have to replace with the inferior contains(). In fact I'm really struggling with alias still.&lt;br /&gt;&lt;br /&gt;One idea is to develop this family history with my brother Richard and my  nephew, Reddyn, in New Zealand, who I have sadly neglected.  Here we could all work together in a very Web 2.0 collaboration.  Hope they run with the idea.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-113913445636096524?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/113913445636096524/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=113913445636096524&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/113913445636096524'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/113913445636096524'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2006/02/exist-ndx-web-server.html' title='Exist NDX web server'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-113913270658391034</id><published>2006-02-05T09:18:00.000Z</published><updated>2006-03-26T11:10:14.120+01:00</updated><title type='text'>Tag Clouds</title><content type='html'>Just been playing with generating tag clouds, based on the UCAS keywords which I obtained before Christmas.  These are now integrated into the view of programmes, but perhaps all such relationships are worth reversing - here keyword to programme - and the obvious way to do this is with a tag cloud.  Ian reminds me of my play with Postscript, generating exam result lists in fonts scaled to the mark itself. The big plus here was that when students were sorted into ascending order of the overall average, you could see at a glance how well each separate exam correlated with the overall.&lt;br /&gt;&lt;br /&gt;My tag cloud uses xquery and xslt.  First pass to compute the tags and counts, then compute min and max counts from this computed element, and a scaling factor, all in Xquery.  XSLT generates the cloud, computing a fontsize based on the count.  All a bit slow but it does the job.&lt;br /&gt;&lt;br /&gt;I've also just realised a feature of most clouds I've seen - double description [Bateson].  That is tags are not only scaled in size but intensity is increased as well. &lt;a href="http://newzingo.com/UK"&gt; Newzingo&lt;/a&gt; uses a 7 point scale, not the continuous  variation I'd  assumed from my  Postscript days, where both font size and red intensity increase together.  Clouds differ in the link styles - default isnt appropriate since it's just a page of links, but just what style is best?  I've set  the title attribute on my tags, containing the course codes themselves for a quick check but this seems to conflict with hover styling.&lt;br /&gt;&lt;br /&gt;But I wonder how to use the comparative idea here - so that keywords in one faculty can be contrasted with those in another, in order to visualise the difference between the two faculties.  Perhaps the trick would be a single map which can be dynamicly switched between the two - perhaps even programmed to do so, like a flicker star-map comparator.  I would need to get the two maps to register, so that there is a single merged map, but words can be turned on or off - perhaps I'd have to drop the size scaling since this will alter the position of text.  Just coluring the text by coding for the datasets and varying the intensity proportional to importance.  &lt;br /&gt;&lt;br /&gt;Since our new VC seems likely to be merging faculties, this might be a useful tool for him to see which ones to merge - quelle horreur - its just the way this visualisation might be used!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-113913270658391034?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/113913270658391034/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=113913270658391034&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/113913270658391034'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/113913270658391034'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2006/02/tag-clouds.html' title='Tag Clouds'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-113779828397743410</id><published>2006-01-20T23:01:00.000Z</published><updated>2006-01-23T08:27:24.843Z</updated><title type='text'>More Google mashups</title><content type='html'>More play with map-based mashups.  This evening, using &lt;a href="http://www.programmableweb.com/mashups"&gt;&lt;span style="text-decoration: underline;"&gt;programmableweb's listing&lt;/span&gt;&lt;/a&gt; , I found Flash Earth, a Google Earth mashup.    Here's the link to a &lt;a href="http://www.flashearth.com/?lat=29.520987&amp;lon=35.423554&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;z=14&amp;r=0&amp;amp;src=0"&gt;narrow siq&lt;/a&gt; in the Wadi Rum area in Jordan, one of several with old inscriptions carved in the sandstone.&lt;br /&gt;&lt;br /&gt;This &lt;a href="http://bryngfors.com/index.php?page_id=10"&gt;memory game&lt;/a&gt; is a neat idea, using yahoo images to populate a layout of images to play pairs (or memory).&lt;br /&gt;&lt;br /&gt;But my favourite is &lt;a href="http://www.communitywalk.com/"&gt;Community Walk&lt;/a&gt;  Last night I started to create a walk around the &lt;a href="http://www.communitywalk.com/map/1681"&gt;university campus&lt;/a&gt; - just a single, rather bland view of our building - perhaps this is not such a good idea if we want to attract students.  Later I started one for our &lt;a href="http://www.communitywalk.com/map/1718"&gt;trip to Jordan&lt;/a&gt;.  Just three photos uploaded at present, and I'm uncertain about the location of one of these - I can''t seem to find the location of Petra.  I do wish I'd keep the GPS data since I had the Garmin with me to check heights and distances, but at that time, the advantages of geo-coding photographs just hadn't occured to me.  Maybe a student project to make a camera and GPS lashup.  What would be really nice would be to add a fluxgate compass too, so the photo is coded with the direction in which the camera was pointing as well. &lt;br /&gt;&lt;br /&gt;Just found another UK mashup of all &lt;a href="http://www.schoolmap.org.uk/"&gt;UK schools&lt;/a&gt;  It shows the location of all UK schools, locates the nearest 20 to a specified location, highlights the marker from a list of school names and their Ofsted rating (at least for Independent Schools).&lt;br /&gt;&lt;br /&gt;Finally on this bit of research, located Barry Hunter's work on at nearby.org.uk which offers a &lt;a href="http://www.nearby.org.uk/api/convert-help.php"&gt;REST interface&lt;/a&gt; for conversion between a range of different coordinate systems, e.g. Postcode to Lat/long.  Will be very handy for the FamilyHistory mashup, although the postcode is only down to sector level - not enough accuracy for this application, and I suppose there's not much extra work in hand-coding this number of locations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-113779828397743410?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/113779828397743410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=113779828397743410&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/113779828397743410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/113779828397743410'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2006/01/more-google-mashups.html' title='More Google mashups'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-113754427698216428</id><published>2006-01-17T23:55:00.000Z</published><updated>2006-01-18T00:35:06.486Z</updated><title type='text'>Beginner's Mashup</title><content type='html'>I've been playing with integrating maps into my family history photo album.  The idea is to place each photo in time, place and (through the people in the photo) in the web of family relationships.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.plexle.com/photos.xml"&gt;first attempt&lt;/a&gt; uses an XML file of photo meta-data, transformed with a simple&lt;a href="http://www.plexle.com/photo.xsl"&gt; XSLT &lt;/a&gt;on the client-side. This transformation is to a table of data with links to the raw jpegs, map positions (courtesy of Multimap) and years (thanks wikipedia).  No relationships yet.  Hardly a mashup, since the context data is linked only with URLs.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.plexle.com/gmapphotos.xml"&gt;second attempt&lt;/a&gt; uses Google maps. Now the map is embedded in the photo page, much closer coupling afforded by the use of  Javascript.  The step of including the Google Javascript source is coupled with authorisation via URL parameters- a neat application of the Shanley principle. The &lt;a href="http://www.plexle.com/gmapphoto.xsl"&gt;XSLT&lt;/a&gt; caused me a bit of pain here when generating the Javascript and it's still not right: the transformed HTML works fine in IE6 and if generated client-side with XALAN, but its no good on Firefox which just spins.&lt;br /&gt;&lt;br /&gt;I now have to think how the students will use and develop this example: their server is inside our firewall and so Google won't be able to issue a key. They need a server in the DMZ for this I guess but we need that for the new Internet Applications Development module for September this year.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-113754427698216428?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/113754427698216428/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=113754427698216428&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/113754427698216428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/113754427698216428'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2006/01/beginners-mashup.html' title='Beginner&apos;s Mashup'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-113735277573936778</id><published>2006-01-15T18:46:00.000Z</published><updated>2006-01-15T20:41:35.330Z</updated><title type='text'>The title</title><content type='html'>The title is an echo of &lt;a href="http://www.wku.edu/%7Esmithch/index1.htm"&gt;Alfred Russel Wallace&lt;/a&gt;'s  Line through the Malay Archipeligo which he postulated to explain the differences he observed in bird and animal species.  The line runs between Borneo and Sulawesi, and between Bali and Lombok, Asian species (such as tigers) to the west , Australiasian species (such as marsupials)  to the east.  Nowadays the theory of tectonic plates and land bridges during ice ages provides an explanation for this disjuncture.&lt;br /&gt;&lt;br /&gt;My appropriation is hardly warranted: ARW is no relation of mine, and I'm a teacher of computing, not natural history.  I have crossed the Wallace line however, when a few years ago, my wife and I circumnavigated in our yacht &lt;a href="http://www.perdika.co.uk/"&gt;Perdika of Bristol.&lt;/a&gt;  It was in fact quite a struggle.  The current flow through all these straits is fierce and we crabbed our way from Lombok to Bali, pointing fully 40 degrees north of our track over land, and later when motoring northwards up the strait, finding the inshore counter-current frighteningly close to the Bali shore.&lt;br /&gt;&lt;br /&gt;The title also reflects the nature of a blog, a time-line of writing. I'm interested in time-lines and the representation of complex event-spaces at present, partly as a domain to use in my second year course on data structures which this semester will be looking at XML and XML databases, &lt;a href="http://exist-db.org/"&gt;eXist&lt;/a&gt; in particular.  I've also started to do a bit of genealogical research into my personal 'Wallace Line' and discovered how addictive this detective work is.  From census records available online at &lt;a href="http://www.scotlandspeople.gov.uk/"&gt;scotlandspeople.gov.uk&lt;/a&gt;, I find  that my great-grandfather (or rather one of four of course) Ebenezer Wallace was a wine merchant in Edinburgh in the 1880's, a fact which makes my own consumption of good wines now feel like a family duty.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-113735277573936778?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/113735277573936778/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=113735277573936778&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/113735277573936778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/113735277573936778'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2006/01/title.html' title='The title'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21005140.post-113732371451835352</id><published>2006-01-15T11:11:00.001Z</published><updated>2006-01-15T11:15:14.516Z</updated><title type='text'>The first word</title><content type='html'>I teach internet computing - therefore I must blog.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21005140-113732371451835352?l=thewallaceline.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thewallaceline.blogspot.com/feeds/113732371451835352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21005140&amp;postID=113732371451835352&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/113732371451835352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21005140/posts/default/113732371451835352'/><link rel='alternate' type='text/html' href='http://thewallaceline.blogspot.com/2006/01/first-word_15.html' title='The first word'/><author><name>chris wallace</name><uri>http://www.blogger.com/profile/12694488941042708861</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry></feed>
