1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
"""
A parser filter for namespace support. Placed externally to the parser
for efficiency reasons.
$Id: namespace.py,v 1.5 2001/12/30 12:09:14 loewis Exp $
"""
import string
import xmlapp
# --- ParserFilter
class ParserFilter(xmlapp.Application):
"A generic parser filter class."
def __init__(self):
xmlapp.Application.__init__(self)
self.app=xmlapp.Application()
def set_application(self,app):
"Sets the application to report events to."
self.app=app
# --- Methods inherited from xmlapp.Application
def set_locator(self,locator):
xmlapp.Application.set_locator(self,locator)
self.app.set_locator(locator)
def doc_start(self):
self.app.doc_start()
def doc_end(self):
self.app.doc_end()
def handle_comment(self,data):
self.app.handle_comment(data)
def handle_start_tag(self,name,attrs):
self.app.handle_start_tag(name,attrs)
def handle_end_tag(self,name):
self.app.handle_end_tag(name)
def handle_data(self,data,start,end):
self.app.handle_data(data,start,end)
def handle_ignorable_data(self,data,start,end):
self.app.handle_ignorable_data(data,start,end)
def handle_pi(self,target,data):
self.app.handle_pi(target,data)
def handle_doctype(self,root,pubID,sysID):
self.app.handle_doctype(root,pubID,sysID)
def set_entity_info(self,xmlver,enc,sddecl):
self.app.set_entity_info(xmlver,enc,sddecl)
# --- NamespaceFilter
class NamespaceFilter(ParserFilter):
"""An xmlproc application that processes qualified names and reports them
as 'URI local-part' names. It reports errors through the error reporting
mechanisms of the parser."""
def __init__(self,parser):
ParserFilter.__init__(self)
self.ns_map={} # Current prefix -> URI map
self.ns_stack=[] # Pushed for each element, used to maint ns_map
self.rep_ns_attrs=0 # Report xmlns-attributes?
self.parser=parser
def set_report_ns_attributes(self,action):
"Tells the filter whether to report or delete xmlns-attributes."
self.rep_ns_attrs=action
# --- Overridden event methods
def handle_start_tag(self,name,attrs):
old_ns={} # Reset ns_map to these values when we leave this element
del_ns=[] # Delete these prefixes from ns_map when we leave element
# attrs=attrs.copy() Will have to do this if more filters are made
# Find declarations, update self.ns_map and self.ns_stack
for (a,v) in attrs.items():
if a[:6]=="xmlns:":
prefix=a[6:]
if string.find(prefix,":")!=-1:
self.parser.report_error(1900)
if v=="":
self.parser.report_error(1901)
elif a=="xmlns":
prefix=""
else:
continue
if self.ns_map.has_key(prefix):
old_ns[prefix]=self.ns_map[prefix]
else:
del_ns.append(prefix)
if prefix=="" and v=="":
del self.ns_map[prefix]
else:
self.ns_map[prefix]=v
if not self.rep_ns_attrs:
del attrs[a]
self.ns_stack.append((old_ns,del_ns))
# Process elem and attr names
name=self.__process_name(name)
parts=string.split(name)
if len(parts)>1:
ns=parts[0]
else:
ns=None
for (a,v) in attrs.items():
del attrs[a]
aname=self.__process_name(a,ns)
if attrs.has_key(aname):
self.parser.report_error(1903)
attrs[aname]=v
# Report event
self.app.handle_start_tag(name,attrs)
def handle_end_tag(self,name):
name=self.__process_name(name)
# Clean up self.ns_map and self.ns_stack
(old_ns,del_ns)=self.ns_stack[-1]
del self.ns_stack[-1]
self.ns_map.update(old_ns)
for prefix in del_ns:
del self.ns_map[prefix]
self.app.handle_end_tag(name)
# --- Internal methods
def __process_name(self,name,default_to=None):
n=string.split(name,":")
if len(n)>2:
self.parser.report_error(1900)
return name
elif len(n)==2:
if n[0]=="xmlns":
return name
try:
return "%s %s" % (self.ns_map[n[0]],n[1])
except KeyError:
self.parser.report_error(1902)
return name
elif default_to!=None:
return "%s %s" % (default_to,name)
elif self.ns_map.has_key("") and name!="xmlns":
return "%s %s" % (self.ns_map[""],name)
else:
return name
|