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 pyxb
19 import logging
20
21 _log = logging.getLogger(__name__)
22
23
24 BuiltInObjectUID = pyxb.utils.utility.UniqueIdentifier('PyXB-' + pyxb.__version__ + '-Builtin')
25
26 from pyxb.namespace import Namespace
27
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
62
63
64
65
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
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
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
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
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
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
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
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
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
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
276 BuiltInNamespaces = [
277 XMLSchema_instance,
278 XMLSchema_hfp,
279 XMLSchema,
280 XMLNamespaces,
281 XML,
282 XHTML
283 ]
284
285 __InitializedBuiltinNamespaces = False
286
298
299
300 _UndeclaredNamespaceMap = { }
301 [ _UndeclaredNamespaceMap.setdefault(_ns.boundPrefix(), _ns) for _ns in BuiltInNamespaces if _ns.isUndeclaredNamespace() ]
302