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