1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
25 BuiltInObjectUID = pyxb.utils.utility.UniqueIdentifier('PyXB-' + pyxb.__version__ + '-Builtin')
26
27 from pyxb.namespace import Namespace
28
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
63
64
65
66
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
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
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
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
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
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
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
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
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
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
277 BuiltInNamespaces = [
278 XMLSchema_instance,
279 XMLSchema_hfp,
280 XMLSchema,
281 XMLNamespaces,
282 XML,
283 XHTML
284 ]
285
286 __InitializedBuiltinNamespaces = False
287
299
300
301 _UndeclaredNamespaceMap = { }
302 [ _UndeclaredNamespaceMap.setdefault(_ns.boundPrefix(), _ns) for _ns in BuiltInNamespaces if _ns.isUndeclaredNamespace() ]
303