Topic maps - a new super hero is born!
11 April, 2007The good thing about superheroes is that they’re there when you need them. They fly in, seemingly from no where, and save the day. My experience with topic maps has been something like this - when ever I think I’ve got into trouble, messed up the data schema, or need to incorporate new ideas, relationships, or data, topic maps comes to my rescue and doesn’t disappoint.
I know, it sounds a bit weird. People have looked at me and said, “isn’t Topic maps is just xml?” and “Topic maps is nothing great”. Well, lemme explain about the proverbial caped crusader that is topic maps.
I’ve been involved with topic maps projects now for about two years, first at the National Library with the guru of topic maps down-under, Alex Johannessen, and more recently with my work at SMS and a looming uuber engagement for a reporting system that will involve wikis, folksonomies, taxonomies and, importantly topic maps, at a government department.
With SMS, I’ve been working on a skunkworks project for work now for nearly a year now - the Capability Finder. It’s based on a topic maps engine that I developed for my Magia roleplaying website - an engine essentially for content management. I then tweaked and genericised so that it could be effectively used to join the dots between consultants: the work they do; the industries they’re worked in; the skills they have (and even aspire to having); and the engagements they’ve worked on.
Rather than sleep-in every day for four days during the Easter holidays, I was instead woken-up by the sound of XML in my head. The only way to stop the noise was to play with the underlying topic map framework for the Capability Finder for most of this Easter long weekend.
What are topic maps? I’ve dealt with them before in another of my blog posts, but, essentially, they’re a way of representing knowledge and information in the way that people (humans rather than machines) think about the knowledge and information inside their heads - that is, in terms of relationships, rather than a strict hierarchy (a taxonomy) or an unstructured cloud of tags (folksonomy).
So, there I was, playing with the topic map. The structure had evolved over time and there were many inconsistencies in the xml data schema (I don’t like to use the overly verbose ISO standard. I use one I adopted from Alex). Some things that I had as properties of a topic (essentially metadata elements) should have been expressed as relationships.
Here’s an example:
<topic id="matthew-hodgson" type="consultant">
<name>Matthew Hodgson</name>
…etc…
<property type=”EngagementCurrentTitle”>Big Agency Engagement</property>
<property type=”EngagementCurrentDateStart”>April 2006</property>
</topic>
This is perfectly fine, but it doesn’t represent the actual nature of the relationship between the two topics:
- the topic Matthew the consultant
- the topic Matthew’s current engagement
I should have represented the xml something like this:
<topic id=”matthew-hdogson” type=”consultant”>
<name>Matthew Hodgson</name>
…etc…
</topic><association id="engagement-association-big-agency-engagement" type="engagement-family">
<member role=”lead-consultant” refid=”matthew-hodgson”/>
<member role=”engagement” refid=”big-agency-engagement-203893″ />
</association><topic id="big-agency-engagement-203893" type="project-engagement">
<property type=”dc.date.start” refid=”ISO8601″>2006-04-23T00:00:00+10:00</property>
<property type=”status”>active</property>
</topic>
Part of why I don’t like databases is that if I had’ve made this error in judgement in a database I’d have to rebuild the database (probably from scratch). Fortunately, I had a superhero on my wide - topic maps as xml. Because of this, all I needed to do was to transform the existing xml into a new xml file using xsl.
<xsl:for-each select="topic">
<topic id=”{@id}” type=”{@type}” >
<name><xsl:value-of select=”name”/></name>
<xsl:for-each select=”property”>
<xsl:if test=”not(contains(@type, ‘Engagement’))”>
<property type=”{@type}” refid=”{@refid}” >
<xsl:apply-templates select=”.”/></property>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
<xsl:for-each select="topic[@type='consultant' and
not(normalize-space(property[@type='EngagementCurrentTitle'])=”) and
not(normalize-space(property[@type='EngagementCurrentTitle'])=’No details available’)]”>
<xsl:variable name=”engagement-title”
select=”translate(property[@type='EngagementCurrentTitle'], ‘ ‘, ”)” />
<topic id=”engagement-{$engagement-title}” type=”engagement”>
<name><xsl:value-of select=”property[@type='EngagementCurrentTitle']“/></name>
<property type=”active” refid=”true”/>
<property type=”dc.date.end” refid=”ISO8601″>
<xsl:value-of select=”property[@type='dc.date.EngagementCurrentConcludes']“/>
</property>
<property type=”dc.date.start” refid=”ISO8601″></property>
<property type=”engagement-summary-document” refid=”#” />
</topic>
<association id=”assoc-{$engagement-title}” type=”engagement-family”>
<member refid=”{@id}” role=”project-lead-consultant” />
<member refid=”engagement-{$engagement-title}” role=”project” />
</association>
</xsl:for-each>
So, after being rescued by my superhero, I then moved to working on the xsl page that presents the information as XHTML so that this new relationship could be presented as hyperlinks. This would allow someone to arrive at a consultant, see the engagement relationship, click on it, and be taken to the engagement he was working on. On that page, you would see all the engagement information, skills used, industry it belongs to, documents attached as engagement summaries or even just engagement deliberables and reports. You could click on any of those and explore further.
These “super powers” of topic maps are probably what I like the best - that is, expressing the relationships as hyperlinks. It’s not about leaping tall data stores in a single bound - at the end of the day, it’s about navigability and findability.
So, next time you need a superhero, don’t look to rigid hierarchical databases. Send the bat-signal into the heavens and call upon topic maps to save the day.
M
Posted by magia3e










