technology from back to front

Archive for January, 2008

Some simple examples of using Erlang’s XPath implementation

We’ve been investigating the possibility of an XPath-based routing extension to RabbitMQ, where XPath would be used as binding patterns, and the message structure would be exposed as XML infoset. As part of this work, we’ve been looking at Erlang’s XPath implementation that comes as part of the built-in xmerl library.

Here are a couple of examples of Erlang’s XPath in action. First, let’s parse a document to be queried:

{ParsedDocumentRootElement, _RemainingText = ""} =
  xmerl_scan:string("<foo>" ++
                      "<myelement myattribute=\"red\">x</myelement>" ++
                      "<myelement myattribute=\"blue\">x</myelement>" ++
                      "<myelement myattribute=\"blue\">y</myelement>" ++

(We could have used xmerl\_scan:file to read from an external file, instead of xmerl\_scan:string, if we’d wanted to.)

Next, let’s retrieve the contents of every myelement node that contains text exactly matching “x”:

69> xmerl_xpath:string("//myelement[. = 'x']/text()",
[#xmlText{parents = [{myelement,1},{foo,1}],
          pos = 1,
          language = [],
          value = "x",
          type = text},
 #xmlText{parents = [{myelement,2},{foo,1}],
          pos = 1,
          language = [],
          value = "x",
          type = text}]

Notice that it’s returned two XML text nodes, and that the “parents” elements differ, corresponding to the different paths through the source document to the matching nodes.

Next, let’s search for all myelements that have a myattribute containing the string “red”:

72> xmerl_xpath:string("//myelement[@myattribute='red']",
     name = myelement,
     expanded_name = myelement,
     nsinfo = [],
     namespace = #xmlNamespace{default = [],nodes = []},
     parents = [{foo,1}],
     pos = 1,
     attributes = 
              name = myattribute,
              expanded_name = [],
              nsinfo = [],
              namespace = [],
              parents = [],
              pos = 1,
              language = [],
              value = "red",
              normalized = false}],
     content = 
              parents = [{myelement,1},{foo,1}],
              pos = 1,
              language = [],
              value = "x",
              type = text}],
     language = [],
     xmlbase = "/localhome/tonyg",
     elementdef = undeclared}]

This time, there’s only the one match. Finally, a query that no nodes satisfy:

75> xmerl_xpath:string("//myelement[@myattribute='red' and . = 'y']",

If we had replaced the 'y' with 'x', we’d have retrieved a non-empty nodeset.


New .NET/C# client library for RabbitMQ

We’ve just finished and released our .NET/C# client library for AMQP. We developed it on Mono, and made sure it ran on the Microsoft .NET stacks as well – versions 1.1 and 2.0. There’s also a WCF binding, for exposing WCF-based services over AMQP. (The WCF binding only compiles and runs on the Microsoft CLR implementations, until Mono’s Olive WCF implementation matures a little, anyway.)

One interesting thing about the library is its support for more than just one protocol variant: it speaks AMQP 0-8 as standardised, AMQP 0-8 as extended by QPid, and AMQP 0-9 as standardised (sans the bits of the spec marked “work in progress”, ie. the Message class). You can switch protocol variants at runtime, and there’s a common interface that abstracts away from the incompatibilities in the protocol variants. We’ve run the library against RabbitMQ (of course), as well as QPid-java and OpenAMQ 1.2c4.

The library is documented in a PDF user guide, which actually contains quite a bit of useful general AMQP information and guidelines, and could form the core of a language-neutral RabbitMQ manual. The detailed API guide is also available – you can download the code, the binaries, and all the different reformattings of the documentation on the interim page for the .NET/C# client library.

Our RabbitMQ website is starting to look a bit messy, so we’re working on a revised layout that should be a bit tidier; then, the .NET stuff will be presented alongside all the other client libraries and bindings we have available, rather than being presented as a separate-looking piece.


NDocProc bug fix for empty namespaces

Thanks to a comment from Claus, I’ve discovered the wonderful fact that null is not permitted as a key in an IDictionary in .NET. As it happens, the main problem was that I’d not covered namespaceless classes in NDocProc at all gracefully, but nonetheless, forbidding nulls as dictionary keys is a strange design decision.

I’ve fixed the bug, and now NDocProc handles types with no namespace much more gracefully. I’ve updated the repository:

hg clone

and there’s a snapshot (source and binary) available, as well:


OLPC v. the Intel Classmate in Nigeria

Tony directed me to this documentary (BBC iPlayer, so probably only valid in the UK and for a few days) about the One-Laptop-Per-Child pilot scheme in Nigeria. It also covers an ostensibly similar pilot run by Intel with its Classmate PC. Intel recently pulled out of supporting OLPC, saying among other things that competition was the best way to achieve both projects’ goals.

Although the documentary only touches the surface, two things are clear: the kids involved love having the computers (both varieties), but otherwise these pilots have little in common. The Intel folk have splashed money about, and happily admit that they have not entirely charitable goals — of course they are trying to open up a market. On the other hand, one local educator involved in the OLPC pilot insisted that the laptops were only a detail of the programme: the goal was to empower the kids to improve their lot.

The difference that most struck me was embodied in the laptops themselves. The Classmates are, and look like, small notebooks with some token robustification. They cost about $400 and run Windows XP. At the end of the school day, they are taken from the children.

The XOs are designed for being carried around by kids. Not only do they have dust- and shock-proofing, but they are also designed to be kid-proof when opened up. They cost $200 and run an operating system made specifically for the OLPC programme, with wireless mesh networking. The kids can take them home after school.

Aside from giving better access to educational materials, what are these laptops going to teach the children? The Classmate will teach them to use Windows XP. The XO will teach them to engage with technology, to tinker and hack and share discoveries. One child was teaching his father how to use the XO in the evenings. Another kid who had previously been struggling at school had become the class XO expert, helping the others fix hardware problems.

The difference, then, is between manufacturing dependency and teaching self-sufficiency. Intel are wrong to say that competition will help achieve both goals, because their goal is opposed to OLPC’s goal; but competition from Intel could easily kill OLPC, and it would be a huge opportunity wasted.


Trac custom workflow

I’ve been experimenting with Trac’s new customisable work-flow. This hasn’t made it into a stable release yet – I’m using the trunk source. Hopefully Trac 0.11 is not far away. The first beta has been released.

It looks very promising: plug-ins may return lists of actions they allow, given the current state of the ticket. Actions can render their own controls, so they can include inputs to be entered when the user selects the action. There is also a default work-flow plug-in which allows you to specify a state graph in trac.ini. It’s even possible to compose multiple work-flow plug-ins – all the actions offered by each plug-in are displayed to the user. The default work-flow plug-in can be queried for information about its configuration.

On the down side – it seems essential for the work-flow plug-ins to use fields in the ticket the user can’t edit. Trac does this itself – you can’t directly edit ‘status’, ‘owner’ or ‘resolution’. A hack is just to create a plugin that protects a list of fields from being changed, but the user must discover by trial and error what can and can’t be edited. There is also no way for an action to reject input from its own controls.

I’ve started using Trac on a collaborative project with a client. We normally use bugzilla, so we are used to having a separate QA contact, and having Bugzilla track the functional QA process. We use flags for peer QA, but Trac could handle this with work-flow as well, and that would be desirable.

So far, I can’t quite get this to the point where it’s sufficiently user friendly for its intended audience. Hopefully it won’t be long before I can.

You can find out more about Trac here, and more specifically about the upcoming release here.


GNU Smalltalk Cairo Clock Demo

ScreenshotI’ve taken Mike Anderson’s Cairo clock applet demo and updated it ever so slightly for GNU Smalltalk version 2.95h.

* the original tarball: clockdemo.tgz (and a mirror)
* patch for getting it to work with gst-2.95h: fixes-2.95h.patch

I’ve also written a small patch, available here, intended to apply atop fixes-2.95h.patch, which gets the code into a position where it will run without change on both my stock Debian x86 desktop as well as my OS X 10.3.9 box with a prehistoric Fink 0.7.2 and a hand-compiled libcairo.


GNU Smalltalk 2.95h on Mac OS X 10.3.9

GNU Smalltalk version 2.95h (the latest release candidate) didn’t compile out-of-the-box on Mac OS X 10.3.9 for me. The two changes that were required were:

* change the header file includes in socketx.h to the older way of getting the prototypes for select(2)
* change part of a .section declaration in darwin\_closure.S to remove mention of the live\_support section attribute.

After these changes, gst compiles and runs well for me on my OS X 10.3.9 box.

The patch against gst 2.95h is here.




You are currently browsing the LShift Ltd. blog archives for January, 2008.



2000-14 LShift Ltd, 1st Floor, Hoxton Point, 6 Rufus Street, London, N1 6PE, UK+44 (0)20 7729 7060   Contact us