diff --git a/courseware/capa_module.py b/courseware/capa_module.py index 0948518bb7..28b7f641f7 100644 --- a/courseware/capa_module.py +++ b/courseware/capa_module.py @@ -115,7 +115,7 @@ class LoncapaModule(XModule): dom2 = etree.fromstring(xml) - self.explanation=content_parser.item(dom2.xpath('/problem/@explain')) + self.explanation=content_parser.item(dom2.xpath('/problem/@explain'), default="closed") self.explain_available=content_parser.item(dom2.xpath('/problem/@explain_available')) self.due_date=content_parser.item(dom2.xpath('/problem/@due')) diff --git a/courseware/content_parser.py b/courseware/content_parser.py index bfeab1db6f..5d91eb8d06 100644 --- a/courseware/content_parser.py +++ b/courseware/content_parser.py @@ -11,6 +11,30 @@ course XML file and the rest of the system. TODO: Shift everything from xml.dom.minidom to XPath (or XQuery) ''' +def xpath(xml, query_string, **args): + ''' Safe xpath query into an xml tree: + * xml is the tree. + * query_string is the query + * args are the parameters. Substitute for {params}. ''' + doc = etree.fromstring(xml) + print type(doc) + def escape(x): + # TODO: This should escape the string. For now, we just assume it's made of valid characters. + # Couldn't figure out how to escape for lxml in a few quick Googles + valid_chars="".join(map(chr, range(ord('a'),ord('z')+1)+range(ord('A'),ord('Z')+1)+range(ord('0'), ord('9')+1)))+"_ " + for e in x: + if e not in valid_chars: + raise Exception("Invalid char in xpath expression. TODO: Escape") + return x + + args=dict( ((k, escape(args[k])) for k in args) ) + print args + results = doc.xpath(query_string.format(**args)) + return results + +if __name__=='__main__': + print xpath('', '/{search}/problem[@name="{name}"]', search='html', name="Bob") + def item(l, default="", process=lambda x:x): if len(l)==0: return default diff --git a/settings.py b/settings.py index 6dd38e683a..f080316198 100644 --- a/settings.py +++ b/settings.py @@ -103,6 +103,7 @@ INSTALLED_APPS = ( 'django.contrib.humanize', 'static_template_view', 'textbook', + 'staticbook', # Uncomment the next line to enable the admin: # 'django.contrib.admin', # Uncomment the next line to enable admin documentation: diff --git a/urls.py b/urls.py index d9c0c9801b..dbc5c5ab36 100644 --- a/urls.py +++ b/urls.py @@ -19,6 +19,7 @@ urlpatterns = patterns('', # url(r'^accounts/', include('registration.urls')), url(r'^t/(?P