Package pyxb :: Package namespace :: Module builtin
[hide private]
[frames] | no frames]

Source Code for Module pyxb.namespace.builtin

  1  # -*- coding: utf-8 -*- 
  2  # Copyright 2009-2013, Peter A. Bigot 
  3  # 
  4  # Licensed under the Apache License, Version 2.0 (the "License"); you may 
  5  # not use this file except in compliance with the License. You may obtain a 
  6  # copy of the License at: 
  7  # 
  8  #            http://www.apache.org/licenses/LICENSE-2.0 
  9  # 
 10  # Unless required by applicable law or agreed to in writing, software 
 11  # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
 12  # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
 13  # License for the specific language governing permissions and limitations 
 14  # under the License. 
 15   
 16  """Classes and global objects related to built-in U{XML Namespaces<http://www.w3.org/TR/2006/REC-xml-names-20060816/index.html>}.""" 
 17   
 18  import pyxb 
 19  import logging 
 20   
 21  _log = logging.getLogger(__name__) 
 22   
 23  # A unique identifier for components that are built-in to the PyXB system 
 24  BuiltInObjectUID = pyxb.utils.utility.UniqueIdentifier('PyXB-' + pyxb.__version__ + '-Builtin') 
 25   
 26  from pyxb.namespace import Namespace 
 27   
28 -class _XMLSchema_instance (Namespace):
29 """Extension of L{Namespace} that pre-defines components available in the 30 XMLSchema Instance namespace.""" 31 32 PT_strict = 'strict' 33 """xsi:type is validated and supersedes the declared type. If no xsi:type is 34 present, the declared element type will be used. If xsi:type is 35 present, it must resolve to valid type. The resolved type must be 36 a subclass of the declared type (if available), and will be used 37 for the binding.""" 38 39 PT_lax = 'lax' 40 """xsi:type supersedes the declared type without validation. If 41 no xsi:type is present, or it is present and fails to resolve to a 42 type, the declared element type will be used. If xsi:type is 43 present and resolves to valid type, that type will be used for the 44 binding, even if it is not a subclass of the declared type.""" 45 46 PT_skip = 'skip' 47 """xsi:type attributes are ignored. The declared element type 48 will be used.""" 49 50 __processType = PT_strict 51 52 type = None 53 """An expanded name for {http://www.w3.org/2001/XMLSchema-instance}type.""" 54 55 nil = None 56 """An expanded name for {http://www.w3.org/2001/XMLSchema-instance}nil.""" 57
58 - def __init__ (self, *args, **kw):
59 super(_XMLSchema_instance, self).__init__(*args, **kw) 60 self.type = self.createExpandedName('type') 61 self.nil = self.createExpandedName('nil')
62 63 # NB: Because Namespace instances are singletons, I've made this 64 # is an instance method even though it looks and behaves like a 65 # class method.
66 - def ProcessTypeAttribute (self, value=None):
67 """Specify how PyXB should interpret U{xsi:type 68 <http://www.w3.org/TR/xmlschema-1/#xsi_type>} attributes when 69 converting a document to a binding instance. 70 71 The default value is L{PT_strict}. 72 73 xsi:type should only be provided when using an abstract class, 74 or a concrete class that happens to be the same as the 75 xsi:type value, or when accepting a wildcard that has an 76 unrecognized element name. In practice, web services tend to 77 set it on nodes just to inform their lax-processing clients 78 how to interpret the value. 79 80 @param value: One of L{PT_strict}, L{PT_lax}, L{PT_skip}, or C{None} (no change) 81 @return: The current configuration for processing xsi:type attributes 82 """ 83 84 if value in (self.PT_strict, self.PT_lax, self.PT_skip): 85 self.__processType = value 86 elif value is not None: 87 raise pyxb.ValueError(value) 88 return self.__processType
89
90 - def _InterpretTypeAttribute (self, type_name, ns_ctx, fallback_namespace, type_class):
91 """Interpret the value of an xsi:type attribute as configured 92 by L{ProcessTypeAttribute}. 93 94 @param type_name: The QName value from U{xsi:type 95 <http://www.w3.org/TR/xmlschema-1/#xsi_type>}. If this is 96 C{None}, C{type_class} is used as C{ret_type_class}. 97 98 @param ns_ctx: The NamespaceContext within which C{type_name} 99 should be resolved 100 101 @param fallback_namespace: The namespace that should be used 102 if C{type_name} has no prefix 103 104 @param type_class: The value to return if C{type_name} is 105 missing or acceptably invalid (viz., due to L{PT_skip}) 106 107 @return: A tuple C{(did_replace, ret_type_class)} where 108 C{did_replace} is C{True} iff the C{ret_type_class} is not the 109 same as C{type_class}, and C{ret_type_class} is the class that 110 should be used. 111 112 @raises pyxb.BadDocumentError: if the processing type 113 configuration is L{PT_strict} and C{type_name} fails to 114 resolve to a type definition that is consistent with any 115 provided C{type_class}. 116 """ 117 did_replace = False 118 if type_name is None: 119 return (did_replace, type_class) 120 pt = self.__processType 121 if self.PT_skip == pt: 122 return (did_replace, type_class) 123 type_en = ns_ctx.interpretQName(type_name, namespace=fallback_namespace) 124 try: 125 alternative_type_class = type_en.typeBinding() 126 except KeyError: 127 alternative_type_class = None 128 if self.PT_strict == pt: 129 if alternative_type_class is None: 130 raise pyxb.BadDocumentError('No type binding for %s' % (type_name,)) 131 if (type_class is not None) and (not (type_class._IsUrType() or issubclass(alternative_type_class, type_class))): 132 raise pyxb.BadDocumentError('%s value %s is not subclass of element type %s' % (type_name, type_en, type_class._ExpandedName)) 133 if (self.PT_strict == pt) or ((self.PT_lax == pt) and (alternative_type_class is not None)): 134 type_class = alternative_type_class 135 did_replace = True 136 return (did_replace, type_class)
137
138 - def _defineBuiltins_ox (self, structures_module):
139 """Ensure this namespace is ready for use. 140 141 Overrides base class implementation, since there is no schema 142 for this namespace. """ 143 144 assert structures_module is not None 145 schema = structures_module.Schema(namespace_context=self.initialNamespaceContext(), schema_location="URN:noLocation:PyXB:xsi", generation_uid=BuiltInObjectUID, _bypass_preload=True) 146 schema._addNamedComponent(structures_module.AttributeDeclaration.CreateBaseInstance('type', schema)) 147 schema._addNamedComponent(structures_module.AttributeDeclaration.CreateBaseInstance('nil', schema)) 148 schema._addNamedComponent(structures_module.AttributeDeclaration.CreateBaseInstance('schemaLocation', schema)) 149 schema._addNamedComponent(structures_module.AttributeDeclaration.CreateBaseInstance('noNamespaceSchemaLocation', schema)) 150 return self
151
152 -class _XML (Namespace):
153 """Extension of L{Namespace} that pre-defines components available in the 154 XML (xml) namespace. Specifically those are the attribute declarations: 155 156 - C{xml:space} 157 - C{xml:lang} 158 - C{xml:base} 159 - C{xml:id} 160 161 the encompassing attribute group declaration: 162 163 - C{xml:specialAttrs} 164 165 and the anonymous types that support these.""" 166
167 - def _defineBuiltins_ox (self, structures_module):
168 """Ensure this namespace is ready for use. 169 170 Overrides base class implementation, since there is no schema 171 for this namespace. """ 172 173 assert structures_module is not None 174 import pyxb.binding.datatypes as xsd 175 from pyxb.namespace import archive 176 177 self.configureCategories([archive.NamespaceArchive._AnonymousCategory()]) 178 179 schema = structures_module.Schema(namespace_context=self.initialNamespaceContext(), schema_location="URN:noLocation:PyXB:XML", generation_uid=BuiltInObjectUID, _bypass_preload=True) 180 181 std_space = structures_module.SimpleTypeDefinition._CreateXMLInstance('space', schema) 182 std_space._setAnonymousName(self, anon_name='STD_ANON_space') 183 std_space._setBindingNamespace(self) 184 std_lang = structures_module.SimpleTypeDefinition._CreateXMLInstance('lang', schema) 185 std_lang._setAnonymousName(self, anon_name='STD_ANON_lang') 186 std_lang._setBindingNamespace(self) 187 188 base = schema._addNamedComponent(structures_module.AttributeDeclaration.CreateBaseInstance('base', schema, std=xsd.anyURI.SimpleTypeDefinition())) 189 id = schema._addNamedComponent(structures_module.AttributeDeclaration.CreateBaseInstance('id', schema, std=xsd.ID.SimpleTypeDefinition())) 190 space = schema._addNamedComponent(structures_module.AttributeDeclaration.CreateBaseInstance('space', schema, std=std_space)) 191 lang = schema._addNamedComponent(structures_module.AttributeDeclaration.CreateBaseInstance('lang', schema, std=std_lang)) 192 193 schema._addNamedComponent(structures_module.AttributeGroupDefinition.CreateBaseInstance('specialAttrs', schema, [ 194 structures_module.AttributeUse.CreateBaseInstance(schema, space), 195 structures_module.AttributeUse.CreateBaseInstance(schema, base), 196 structures_module.AttributeUse.CreateBaseInstance(schema, lang), 197 structures_module.AttributeUse.CreateBaseInstance(schema, id), 198 ])) 199 200 return self
201
202 -class _XMLSchema (Namespace):
203 """Extension of L{Namespace} that pre-defines components available in the 204 XMLSchema namespace. 205 206 The types are defined when L{pyxb.xmlschema.structures} is imported. 207 """ 208
209 - def _defineBuiltins_ox (self, structures_module):
210 """Register the built-in types into the XMLSchema namespace.""" 211 212 # Defer the definitions to the structures module 213 assert structures_module is not None 214 structures_module._AddSimpleTypes(self) 215 216 # A little validation here 217 assert structures_module.ComplexTypeDefinition.UrTypeDefinition() == self.typeDefinitions()['anyType'] 218 assert structures_module.SimpleTypeDefinition.SimpleUrTypeDefinition() == self.typeDefinitions()['anySimpleType'] 219 220 # Provide access to the binding classes 221 self.configureCategories(['typeBinding', 'elementBinding']) 222 for ( en, td ) in self.typeDefinitions().items(): 223 if td.pythonSupport() is not None: 224 self.addCategoryObject('typeBinding', en, td.pythonSupport())
225 226 XMLSchema_instance = _XMLSchema_instance('http://www.w3.org/2001/XMLSchema-instance', 227 description='XML Schema Instance', 228 builtin_namespace='XMLSchema_instance') 229 """Namespace and URI for the XMLSchema Instance namespace. This is always 230 built-in, and does not (cannot) have an associated schema.""" 231 232 XMLNamespaces = Namespace('http://www.w3.org/2000/xmlns/', 233 description='Namespaces in XML', 234 builtin_namespace='XMLNamespaces', 235 is_undeclared_namespace=True, 236 bound_prefix='xmlns') 237 """Namespaces in XML. Not really a namespace, but is always available as C{xmlns}.""" 238 239 # http://www.w3.org/2001/XMLSchema.xsd 240 XMLSchema = _XMLSchema('http://www.w3.org/2001/XMLSchema', 241 description='XML Schema', 242 builtin_namespace='XMLSchema', 243 builtin_module_path='pyxb.binding.datatypes', 244 in_scope_namespaces = { 'xs' : None }) 245 """Namespace and URI for the XMLSchema namespace (often C{xs}, or C{xsd})""" 246 247 # http://www.w3.org/1999/xhtml.xsd 248 XHTML = Namespace('http://www.w3.org/1999/xhtml', 249 description='Family of document types that extend HTML', 250 builtin_namespace='XHTML', 251 default_namespace=XMLSchema) 252 """There really isn't a schema for this, but it's used as the default 253 namespace in the XML schema, so define it.""" 254 255 # http://www.w3.org/2001/xml.xsd 256 XML = _XML('http://www.w3.org/XML/1998/namespace', 257 description='XML namespace', 258 builtin_namespace='XML', 259 builtin_module_path='pyxb.binding.xml_', 260 is_undeclared_namespace=True, 261 bound_prefix='xml', 262 default_namespace=XHTML, 263 in_scope_namespaces = { 'xs' : XMLSchema }) 264 """Namespace and URI for XML itself (always available as C{xml})""" 265 266 # http://www.w3.org/2001/XMLSchema-hasFacetAndProperty 267 XMLSchema_hfp = Namespace('http://www.w3.org/2001/XMLSchema-hasFacetAndProperty', 268 description='Facets appearing in appinfo section', 269 builtin_namespace='XMLSchema_hfp', 270 default_namespace=XMLSchema, 271 in_scope_namespaces = { 'hfp' : None 272 , 'xhtml' : XHTML }) 273 """Elements appearing in appinfo elements to support data types.""" 274 275 # List of built-in namespaces. 276 BuiltInNamespaces = [ 277 XMLSchema_instance, 278 XMLSchema_hfp, 279 XMLSchema, 280 XMLNamespaces, 281 XML, 282 XHTML 283 ] 284 285 __InitializedBuiltinNamespaces = False 286
287 -def _InitializeBuiltinNamespaces (structures_module):
288 """Invoked at the end of the L{pyxb.xmlschema.structures} module to 289 initialize the component models of the built-in namespaces. 290 291 @param structures_module: The L{pyxb.xmlschema.structures} module may not 292 be importable by that name at the time this is invoked (because it is 293 still being processed), so it gets passed in as a parameter.""" 294 global __InitializedBuiltinNamespaces 295 if not __InitializedBuiltinNamespaces: 296 __InitializedBuiltinNamespaces = True 297 [ _ns._defineBuiltins(structures_module) for _ns in BuiltInNamespaces ]
298 299 # Set up the prefixes for xml, xmlns, etc. 300 _UndeclaredNamespaceMap = { } 301 [ _UndeclaredNamespaceMap.setdefault(_ns.boundPrefix(), _ns) for _ns in BuiltInNamespaces if _ns.isUndeclaredNamespace() ] 302