From c2dbe20e34ede3745918ff81ac539a2d1c863fd2 Mon Sep 17 00:00:00 2001 From: Thomas Leonard Date: Tue, 13 May 2003 16:37:16 +0000 Subject: [PATCH] Switch searching over to new namespace system. git-svn-id: http://dom-editor.googlecode.com/svn/branches/Gtk2@484 ef21e15d-ca94-4315-9c45-0d95b1b2e117 --- Dome/GUIView.py | 12 +++++------- Dome/Model.py | 5 ++++- Dome/Namespaces.py | 9 +++++++-- Dome/Path.py | 16 ++-------------- Dome/Program.py | 30 ++++++++++++++++++++---------- Dome/View.py | 27 +++++++++------------------ Dome/support.py | 1 + 7 files changed, 48 insertions(+), 52 deletions(-) diff --git a/Dome/GUIView.py b/Dome/GUIView.py index fee25dc..b1f2d7d 100644 --- a/Dome/GUIView.py +++ b/Dome/GUIView.py @@ -185,14 +185,13 @@ class GUIView(Display, XDSLoader): select_region = shift and node.nodeType == Node.ELEMENT_NODE lit = shift and not select_region - ns = {} - path = make_relative_path(src, node, lit, ns) + path = make_relative_path(src, node, lit, self.view.model.namespaces) if path == '.' and self.view.current_nodes and not self.view.current_attrib: return if select_region: - self.view.may_record(["select_region", path, ns]) + self.view.may_record(["select_region", path, "unused"]) else: - self.view.may_record(["do_search", path, ns, add]) + self.view.may_record(["do_search", path, "unused", add]) else: self.view.may_record(["toggle_hidden"]) @@ -201,12 +200,11 @@ class GUIView(Display, XDSLoader): src = self.view.root else: src = self.view.current_nodes[-1] - ns = {} print "attrib_clicked", attrib, attrib.namespaceURI, attrib.localName - path = make_relative_path(src, element, FALSE, ns) + path = make_relative_path(src, element, FALSE, self.view.model.namespaces) if path != '.': - self.view.may_record(["do_search", path, ns, FALSE]) + self.view.may_record(["do_search", path, "unused", FALSE]) self.view.may_record(["attribute", attrib.namespaceURI, attrib.localName]) def menu_save(self): diff --git a/Dome/Model.py b/Dome/Model.py index a194a15..913fafa 100644 --- a/Dome/Model.py +++ b/Dome/Model.py @@ -59,7 +59,8 @@ class Model: for x in root.childNodes: if x.namespaceURI == constants.DOME_NS: if x.localName == 'dome-program': - self.root_program = load_dome_program(x) + self.root_program = load_dome_program(x, + self.namespaces) elif x.localName == 'dome-data': for y in x.childNodes: if y.nodeType == Node.ELEMENT_NODE: @@ -258,6 +259,7 @@ class Model: return new def remove_ns(self, node): + raise Exception("Shouldn't need this now!") nss = GetAllNs(node.parentNode) dns = nss.get(None, None) create = node.ownerDocument.createElementNS @@ -461,6 +463,7 @@ class Model: def prefix_to_namespace(self, node, prefix): "Using attributes for namespaces was too confusing. Keep a global list instead." + if prefix is None: return None try: return self.namespaces.uri[prefix] except KeyError: diff --git a/Dome/Namespaces.py b/Dome/Namespaces.py index 9b6d4da..75f9686 100644 --- a/Dome/Namespaces.py +++ b/Dome/Namespaces.py @@ -3,7 +3,12 @@ from xml.dom import XMLNS_NAMESPACE, XML_NAMESPACE import rox from rox import g -fixed_ns = {'xml': XML_NAMESPACE, 'xmlns': XMLNS_NAMESPACE} +fixed_ns = {'xml': XML_NAMESPACE, 'xmlns': XMLNS_NAMESPACE, + 'dome': 'http://www.ecs.soton.ac.uk/~tal00r/Dome'} + +common_ns = {'http://www.w3.org/1999/xhtml': 'xhtml', + 'http://www.w3.org/1999/02/22-rdf-syntax-ns#': 'rdf', + 'http://xmlns.4suite.org/ext': 'ft'} class Namespaces(g.GenericTreeModel): def __init__(self): @@ -80,7 +85,7 @@ class Namespaces(g.GenericTreeModel): return self.prefix[uri] except KeyError: if not suggested_prefix: - suggested_prefix = 'ns' + suggested_prefix = common_ns.get(uri, 'ns') if suggested_prefix in self.uri: x = 1 while suggested_prefix + `x` in self.uri: x += 1 diff --git a/Dome/Path.py b/Dome/Path.py index 35b34f3..3e03a52 100644 --- a/Dome/Path.py +++ b/Dome/Path.py @@ -4,7 +4,6 @@ def literal_match(node): return "[ext:match('%s')]" % node.nodeValue # Return a string that will match this node in an XPath. -# ns is updated with any new namespace required. def match_name(node, ns): if node.nodeType == Node.TEXT_NODE: return 'text()' @@ -12,24 +11,13 @@ def match_name(node, ns): return 'comment()' elif node.nodeType == Node.ELEMENT_NODE: if node.namespaceURI: - for x in ns.keys(): - if ns[x] == node.namespaceURI: - return '%s:%s' % (x, node.localName) - n = 1 - while 1: - key = '_ns_%d' % n - if not ns.has_key(key): - break - n += 1 - ns[key] = node.namespaceURI - return '%s:%s' % (key, node.localName) + return '%s:%s' % (ns.prefix[node.namespaceURI], node.localName) return node.nodeName else: return node.nodeName def jump_to_sibling(src, dst, ns): "Return an XPath which, given a context 'src' will move to sibling 'dst'." - "Namespace 'ns' may be updated if new names are required" if dst.nodeType == Node.ATTRIBUTE_NODE: return 'attribute::%s/' % dst.nodeName @@ -68,7 +56,7 @@ def path_to(node): def make_relative_path(src_node, dst_node, lit, ns): "Return an XPath string which will move us from src to dst." "If 'lit' then the text of the (data) node must match too." - "Namespace 'ns' is updated with any required namespaces." + "Namespace 'ns' is used to find the prefixes." assert src_node assert dst_node diff --git a/Dome/Program.py b/Dome/Program.py index a18c074..96da7f7 100644 --- a/Dome/Program.py +++ b/Dome/Program.py @@ -10,7 +10,7 @@ def el_named(node, name): return None # Converts a DOM node to a Block object. -def load(node, parent): +def load(node, parent, ns): #assert node.localName == 'block' block = Block(parent) @@ -51,6 +51,14 @@ def load(node, parent): action[0] = 'map' elif action[0] == 'add_attrib': action[1] = "UNUSED" + elif action[0] == 'do_search' and action[2] != 'unused': + print "Converting search namespaces..." + for p, u in action[2].iteritems(): + print "Convert", p, u + new_prefix = ns.ensure_ns(p, u) + action[1] = action[1].replace(p + ':', + new_prefix + ':') + action[2] = 'unused' op = Op(action) elif op_node.localName == 'block': op = load(op_node, block) @@ -103,8 +111,10 @@ def load(node, parent): op.link_to(to, exit) return block -def load_dome_program(prog): - "prog should be a DOM 'dome-program' node." +def load_dome_program(prog, ns): + "prog should be a DOM 'dome-program' node. ns will be updated" + import Namespaces + assert isinstance(ns, Namespaces.Namespaces) #print "Loading", prog if prog.localName != 'dome-program': raise Exception('Not a DOME program: %s!' % prog) @@ -121,7 +131,7 @@ def load_dome_program(prog): done_update = 1 if node.localName == 'block': assert not done_update - new.code = load(node, new) + new.code = load(node, new, ns) if node.localName == 'dome-program': new.add_sub(load_dome_program(node)) @@ -195,7 +205,7 @@ class Program: self.tree_changed() def to_xml(self, doc): - node = doc.createElementNS(DOME_NS, 'dome-program') + node = doc.createElementNS(DOME_NS, 'dome:dome-program') node.setAttributeNS(None, 'name', self.name) node.appendChild(self.code.to_xml(doc)) @@ -368,12 +378,12 @@ class Op: def to_doc(self): from Ft.Xml.cDomlette import implementation - doc = implementation.createDocument(DOME_NS, 'dome-program', None) + doc = implementation.createDocument(DOME_NS, 'dome:dome-program', None) self.to_xml_int(doc.documentElement) return doc def to_xml(self, doc): - node = doc.createElementNS(DOME_NS, 'node') + node = doc.createElementNS(DOME_NS, 'dome:node') node.setAttributeNS(None, 'action', `self.action`) node.setAttributeNS(None, 'dx', str(self.dx)) node.setAttributeNS(None, 'dy', str(self.dy)) @@ -389,14 +399,14 @@ class Op: node.setAttributeNS(None, 'id', str(id(self))) def add_link(op, parent): - node = parent.ownerDocument.createElementNS(DOME_NS, 'link') + node = parent.ownerDocument.createElementNS(DOME_NS, 'dome:link') parent.appendChild(node) node.setAttributeNS(None, 'target', str(id(op))) if self.fail: if self.fail.prev[0] == self: if isinstance(self, Block): - fail = parent.ownerDocument.createElementNS(DOME_NS, 'fail') + fail = parent.ownerDocument.createElementNS(DOME_NS, 'dome:fail') self.fail.to_xml_int(fail) node.appendChild(fail) else: @@ -446,7 +456,7 @@ class Block(Op): Op.link_to(self, child, exit) def to_xml(self, doc): - node = doc.createElementNS(DOME_NS, 'block') + node = doc.createElementNS(DOME_NS, 'dome:block') node.setAttributeNS(None, 'foreach', str(self.foreach)) node.setAttributeNS(None, 'enter', str(self.enter)) node.setAttributeNS(None, 'restore', str(self.restore)) diff --git a/Dome/View.py b/Dome/View.py index bd6c9dc..ebba2ed 100644 --- a/Dome/View.py +++ b/Dome/View.py @@ -608,11 +608,7 @@ class View: if self.op_in_progress and pattern.find('@CURRENT@') == -1: self.op_in_progress.cached_code = code - ns = {} - if not ns: - ns = GetAllNs(self.current_nodes[0]) # XXX - ns['ext'] = FT_EXT_NAMESPACE - #print "ns is", ns + ns = self.model.namespaces.uri c = Context.Context(self.get_current(), processorNss = ns) #print code nodes = code.evaluate(c) @@ -636,9 +632,8 @@ class View: if len(self.current_nodes) == 0: raise Beep src = self.current_nodes[-1] - if not ns: - ns = GetAllNs(src) # XXX - ns['ext'] = FT_EXT_NAMESPACE + + ns = self.model.namespaces.uri c = Context.Context(src, [src], processorNss = ns) rt = XPath.Evaluate(path, context = c) node = None @@ -697,9 +692,7 @@ class View: if self.op_in_progress and pattern.find('@CURRENT@') == -1: self.op_in_progress.cached_code = code - if not ns: - ns = GetAllNs(src) # XXX - ns['ext'] = FT_EXT_NAMESPACE + ns = self.model.namespaces.uri c = Context.Context(src, [src], processorNss = ns) rt = code.evaluate(c) @@ -783,8 +776,7 @@ class View: if self.op_in_progress and expr.find('@CURRENT@') == -1: self.op_in_progress.cached_code = code - ns = GetAllNs(src) # XXX - ns['ext'] = FT_EXT_NAMESPACE + ns = self.model.namespaces.uri c = Context.Context(src, [src], processorNss = ns) rt = code.evaluate(c) @@ -1532,8 +1524,7 @@ class View: def fail_if(self, xpath): """Evaluate xpath as a boolean, and fail if true.""" src = self.get_current() - ns = GetAllNs(src) # XXX - ns['ext'] = FT_EXT_NAMESPACE + ns = self.model.namespaces.uri c = Context.Context(src.parentNode, [src.parentNode], processorNss = ns) rt = XPath.Evaluate(xpath, context = c) @@ -1584,7 +1575,7 @@ class View: self.move_to(node, a) def set_root_from_doc(self, doc): - new = self.root.ownerDocument.importNode(doc.documentElement, 1) + new = self.model.import_with_ns(doc.documentElement) if self.root: self.model.unlock(self.root) @@ -1787,10 +1778,10 @@ class View: pass def export_all(self): - doc = implementation.createDocument(DOME_NS, 'dome', None) + doc = implementation.createDocument(DOME_NS, 'dome:dome', None) node = self.model.root_program.to_xml(doc) doc.documentElement.appendChild(node) - node = doc.createElementNS(DOME_NS, 'dome-data') + node = doc.createElementNS(DOME_NS, 'dome:dome-data') doc.documentElement.appendChild(node) if self.chroots: diff --git a/Dome/support.py b/Dome/support.py index 1b0347c..ed9e654 100644 --- a/Dome/support.py +++ b/Dome/support.py @@ -76,6 +76,7 @@ stuff (eg, MS Word output). Returns None if data is OK""" return data def to_html_doc(data): + "Run data though tidy and return the resulting XML text" (r, w) = os.pipe() child = os.fork() #data = data.replace(' ', ' ') -- 2.11.4.GIT