root/trunk/RBFoundation/RBFoundation/XMLNamespaceMap.py

Revision 752, 5.3 kB (checked in by sholloway, 5 years ago)

--

Line 
1 #!/usr/bin/env python
2 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 ##~ License
4 ##~
5 ##- The RuneBlade Foundation library is intended to ease some
6 ##- aspects of writing intricate Jabber, XML, and User Interface (wxPython, etc.)
7 ##- applications, while providing the flexibility to modularly change the
8 ##- architecture. Enjoy.
9 ##~
10 ##~ Copyright (C) 2002  TechGame Networks, LLC.
11 ##~
12 ##~ This library is free software; you can redistribute it and/or
13 ##~ modify it under the terms of the BSD style License as found in the
14 ##~ LICENSE file included with this distribution.
15 ##~
16 ##~ TechGame Networks, LLC can be reached at:
17 ##~ 3578 E. Hartsel Drive #211
18 ##~ Colorado Springs, Colorado, USA, 80920
19 ##~
20 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21
22 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 #~ Imports
24 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25
26 from __future__ import generators
27 from xml.sax.saxutils import quoteattr as _xmlquoteattr
28
29 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
30 #~ Definitions
31 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32
33 class xmlprefix(str):
34     """A class change to distinguish xml prefixes from a namespace"""
35
36 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37
38 class XMLNamespaceMap(object):
39     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
40     #~ Constants / Variables / Etc.
41     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42
43     __slots__ = ['nextmap', 'xmlnsmap']
44     default_xmlnsmap = {}
45
46     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47     #~ Special Methods
48     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
49
50     def __init__(self, nextmap=None, default_xmlnsmap=None):
51         self.nextmap = nextmap
52         if default_xmlnsmap: self.xmlnsmap = default_xmlnsmap
53         else: self.xmlnsmap = self.default_xmlnsmap.copy()
54
55     def __iter__(self):
56         return self.iterxmlns(False)
57
58     def __contains__(self, key):
59         return key in self.xmlnsmap
60
61     def __len__(self):
62         return len(self.xmlnsmap)
63
64     def __getitem__(self, key):
65         return self.xmlnsmap[key]
66
67     def __setitem__(self, key, value):
68         raise NotImplementedError, "Use setxmlns instead."
69
70     def __delitem__(self, key):
71         del self.xmlnsmap[self.xmlnsmap[key]]
72         del self.xmlnsmap[key]
73
74     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
75     #~ Public Methods
76     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
77
78     def copy(self, klass=None):
79         klass = klass or self.__class__
80         return klass(self.nextmap, default_xmlnsmap=self.xmlnsmap.copy())
81
82     def newchain(self, chainlevel=0, klass=None):
83         klass = klass or self.__class__
84         if chainlevel == 0:
85             return klass(self)
86         elif chainlevel < 0 and self.nextmap:
87             return self.nextmap.newchain(chainlevel+1, klass)
88         else:
89             return klass()
90
91     def get(self, key, default=None):
92         return self.xmlnsmap.get(key, default)
93
94     def setxmlns(self, prefix, xmlns):
95         """Adds an xml namespace mapping entry"""
96         prefix = xmlprefix(prefix or '')
97         try:
98             key = self.xmlnsmap[prefix]
99             del self.xmlnsmap[key]
100         except KeyError: pass
101         try:
102             key = self.xmlnsmap[xmlns]
103             del self.xmlnsmap[key]
104         except KeyError: pass
105         self.xmlnsmap[prefix] = xmlns
106         self.xmlnsmap[xmlns] = prefix
107
108     def _xmlns(self, prefix):
109         return self.xmlnsmap[prefix]
110
111     def xmlns(self, prefix, include_next=True):
112         """Returns the xmlns string, given the prefix string"""
113         try:
114             return self._xmlns(prefix)
115         except KeyError:
116             if include_next and self.nextmap is not None:
117                 return self.nextmap.xmlns(prefix)
118             else:
119                 return None
120
121     def _prefix(self, xmlns):
122         return str(self.xmlnsmap[xmlns])
123
124     def prefix(self, xmlns, include_next=True):
125         """Returns the prefix string, given the xmlns"""
126         try:
127             return self._prefix(xmlns)
128         except KeyError:
129             if include_next and self.nextmap is not None:
130                 return self.nextmap.xmlns(xmlns)
131             else:
132                 return None
133
134     def iterprefix(self, include_next=True):
135         for key, prefix in self.xmlnsmap.iteritems():
136             if not isinstance(key, xmlprefix):
137                 yield prefix, key
138
139         for prefix, ns in include_next and self.nextmap or ():
140             if prefix not in self.xmlnsmap:
141                 yield prefix, ns
142
143     def iterxmlns(self, include_next=True):
144         for key, prefix in self.xmlnsmap.iteritems():
145             if not isinstance(key, xmlprefix):
146                 yield key, prefix
147
148         for prefix, ns in include_next and self.nextmap or ():
149             if prefix not in self.xmlnsmap:
150                 yield ns, prefix
151
152     def xmlstr(self, include_next=False):
153         result = ['']
154         for prefix, xmlns in self.iterprefix(include_next):
155             xmlns = _xmlquoteattr(xmlns)
156             if prefix: result.append('xmlns:%s=%s' % (prefix, xmlns))
157             else: result.append('xmlns=%s' % (xmlns,))
158         return ' '.join(result)
159
Note: See TracBrowser for help on using the browser.