Generating Mind Maps from OU/OpenLearn Structured Authoring XML Documents

One of the really useful things about publishing documents in a structured way is that we can treat the document as a database, or generate an outline view of it automatically.

Whilst looking through the OU Structured Authoring XML docs looking for things I could reliably extract from them in order to configure a course custom search engine (Notes on Custom Course Search Engines Derived from OU Structured Authoring Documents), I put together a quick script to generate a course mind map based around the course structure.

It struck me that as structured document/XML views of OpenLearn material is available, I could do the same for OpenLearn docs. So here’s an example. If you visit the OpenLearn site, you should be able to find several modules derived from the old OU course T175. Going to the first page proper for each of the derived modules (URLs have the form http://openlearn.open.ac.uk/mod/oucontent/view.php?id=398868&direct=1), it is possible to grab a copy of the source XML document for the unit by rewriting the URL to include the setting&content=1: for example, http://openlearn.open.ac.uk/mod/oucontent/view.php?id=398868&content=1 UPDATE: the switch is now &content=scxml

OpenLearn source XML

Downloading the XML files for each of the T175 derived modules on OpenLearn into a single folder, I put together a quick script to mine the structure of the document and pull out the learning objectives for each unit, as well as the headings of each section and subsection. The resulting mindmap provides an outline of the course as a whole, something that can be used to provide a macroscopic view over the whole course, as well as providing a document that could be made available to people following the unit as a resource they could use to organise their notes or annotations around the unit.

T175 on Openlearn mindmap

Download a copy of the T175 on OpenLearn Outline Freemind/.mm mindmap

If we could find a way of getting the OpenLearn page URLs for each section, we could add them in as links within the mindmap, thus allowing it to be used as a navigation surface. (See also MindMap Navigation for Online Courses in this regard.)

Here’s a copy of the Python script I ran over the folder to generate the Freemind mindmap definition file (filetype .mm) based on the section and subsection elements used to structure the document.

# DEPENDENCIES
## We're going to load files in from a course related directory
import os
## Quick hack approach - use lxml parser to parse SA XML files
from lxml import etree
# We may find it handy to generate timestamps...
import time


# CONFIGURATION

## The directory the course XML files are in (separate directory for each course for now) 
SA_XMLfiledir='data'
## We can get copies of the XML versions of Structured Authoring documents
## that are rendered in the VLE by adding &content=1 to the end of the URL
## [via Colin Chambers]
## eg http://learn.open.ac.uk/mod/oucontent/view.php?id=526433&content=1


# UTILITIES

#lxml flatten routine - grab text from across subelements
#via http://stackoverflow.com/questions/5757201/help-or-advice-me-get-started-with-lxml/5899005#5899005
def flatten(el):           
    result = [ (el.text or "") ]
    for sel in el:
        result.append(flatten(sel))
        result.append(sel.tail or "")
    return "".join(result)

#Quick and dirty handler for saving XML trees as files
def xmlFileSave(fn,xml):
	# Output
	txt = etree.tostring(xml, pretty_print=True)
	#print txt
	fout=open(fn,'wb+')
	#fout.write('<?xml version="1.0" encoding="UTF-8" ?>\n')
	fout.write(txt)
	fout.close()


#GENERATE A FREEMIND MINDMAP FROM A SINGLE T151 SA DOCUMENT
## The structure of the T151 course lends itself to a mindmap/tree style visualisation
## Essentially what we are doing here is recreating an outline view of the course that was originally used in the course design phase
def freemindRoot(page):
	tree = etree.parse('/'.join([SA_XMLfiledir,page]))
	courseRoot = tree.getroot()
	mm=etree.Element("map")
	mm.set("version", "0.9.0")
	root=etree.SubElement(mm,"node")
	root.set("CREATED",str(int(time.time())))
	root.set("STYLE","fork")
	#We probably need to bear in mind escaping the text strings?
	#courseRoot: The course title is not represented consistently in the T151 SA docs, so we need to flatten it
	title=flatten(courseRoot.find('CourseTitle'))
	root.set("TEXT",title)
	
	## Grab a listing of the SA files in the target directory
	listing = os.listdir(SA_XMLfiledir)

	#For each SA doc, we need to handle it separately
	for page in listing:
		print 'Page',page
		#Week 0 and Week 10 are special cases and don't follow the standard teaching week layout
		if page!='week0.xml' and page!='week10.xml':
			tree = etree.parse('/'.join([SA_XMLfiledir,page]))
			courseRoot = tree.getroot()
			parsePage(courseRoot,root)
	return mm

def learningOutcomes(courseRoot,root):
	mmlos=etree.SubElement(root,"node")
	mmlos.set("TEXT","Learning Outcomes")
	mmlos.set("FOLDED","true")
	
	los=courseRoot.findall('.//FrontMatter/LearningOutcomes/LearningOutcome')
	for lo in los:
		mmsession=etree.SubElement(mmlos,"node")
		mmsession.set("TEXT",flatten(lo))

def parsePage(courseRoot,root):
	unitTitle=courseRoot.find('.//Unit/UnitTitle')

	mmweek=etree.SubElement(root,"node")
	mmweek.set("TEXT",flatten(unitTitle))
	mmweek.set("FOLDED","true")

	learningOutcomes(courseRoot,mmweek)
	
	sessions=courseRoot.findall('.//Unit/Session')
	for session in sessions:
		title=flatten(session.find('.//Title'))
		mmsession=etree.SubElement(mmweek,"node")
		mmsession.set("TEXT",title)
		mmsession.set("FOLDED","true")
		subsessions=session.findall('.//Section')
		for subsession in subsessions:
			heading=subsession.find('.//Title')
			if heading !=None:
				title=flatten(heading)
				mmsubsession=etree.SubElement(mmsession,"node")
				mmsubsession.set("TEXT",title)
				mmsubsession.set("FOLDED","true")


mm=freemindRoot('t175_1.xml')
print etree.tostring(mm, pretty_print=True)
xmlFileSave('reports/test_t175_full.mm',mm)

If you try to run it over other OpenLearn materials, you may need to tweak the parser slightly. For example, some documents may make use of InnerSection elements, or Header rather than Title elements.

If youdo try using the above script to generate mindmaps/outlines of other OpenLearn courses, please let me know how you got on in the comments below (eg whether you needed to tweak the script, or whether you found other structural elements that could be pulled into the mindmap.)

MindMap Navigation for Online Courses

We’re now a couple of weeks in to a new course (T151) and whilst I’m wary of posting too much about it just at the moment, there a some spinoff thoughts I do want to capture here.

The course is, in part, based on a model of weekly Topic Explorations, where I pose four or five questions and then provide a list of resources for the students to explore, as guided by the questions. An 800 word or so piece then captures some of my observations about the topic.

The structure was informed by a model my colleague John Naughton had used on a different course, and also resembles that of David Wiley’s Blogs, Wikis and New Media course.

One of the questions that came up in a course forum a day or two ago was the course legacy, in terms of access to course materials. The resources I link to from each topic exploration are all web based resources, although some of them are authentication required subscription journal articles, with access provided via the OU Library libezproxy service (the links are also constructed around DOIs, wherever possible).

As part of the Week 0 activities for the course, I provided a quick overview of social bookmarking services, suggesting that students could bookmark those resources that were useful to them, with the advantage that these resource links would still be available once the course had finished and access to the course materials on the VLE withdrawn. (Why we can’t provide a Moodle export version of the materials for students to put in their own Moodle installation at the end of a course, I don’t know? Eg I think NineHub lets you import Moodle courses into their 1-click setup hosted Moodle installations?)

One idea I did entertain was just bookmarking and tagging all the resources so that they could be pulled into the course automatically via an appropriate feed, or alternatively pulled by students into their own space, wherever that might be. The feed powered approach would also make a WiggLE possible ;-)

That’s still possibly on the cards, but instead I began considering another possiblity: delivering the course via an interactive mindmap.

One of the advantages that this offers, also picked up in a forum post, is that it addresses the issue of how and where to take notes: you can take them on the Mindmap. That is, the Mindmap becomes a navigation surface, and a note taking service.

So for example, here’s a fragment of David Wiley’s course, mindmap style (created using Freemind) showing in particular the first week’s resources (see the orginal course material here):

The red arrows identify links – click on a link and the corresponding page will open in a web browser. The course can be viewed and navigated in a far more powerful way than a hierarchical website, becuase mulriple nodes at diffferent levels, and mutliple leaves of the tree can be viewed (or collapsed) at once. The mindmap tool also allows the user to rearrange the spatial layout to suit their own needs. And of course, if they are viewing the mindmap in an interactive mindmap editor, they can add notes as subnodes to any of the resources.

Over the next few days, I think I’ll do T151 in mindmap form, and maybe offer it up as a resource. After all, the course is going out in pilot form, so it’d be foolish not to… ;-)