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 xsi:type attributes when
68 converting a document to a binding instance.
69
70 The default value is L{PT_strict}.
71
72 xsi:type should only be provided when using an abstract class,
73 or a concrete class that happens to be the same as the
74 xsi:type value, or when accepting a wildcard that has an
75 unrecognized element name. In practice, web services tend to
76 set it on nodes just to inform their lax-processing clients
77 how to interpret the value.
78
79 @param value: One of L{PT_strict}, L{PT_lax}, L{PT_skip}, or C{None} (no change)
80 @return: The current configuration for processing xsi:type attributes
81 """
82
83 if value in (self.PT_strict, self.PT_lax, self.PT_skip):
84 self.__processType = value
85 elif value is not None:
86 raise pyxb.ValueError(value)
87 return self.__processType
88
90 """Interpret the value of an xsi:type attribute as configured.
91
92 @param type_name: The QName value from the attribute
93 @param ns_ctx: The NamespaceContext within which the type_name should be resolved
94 @param fallback_namespace: The namespace that should be used if the type name has no prefix
95 @param type_class: The value to return if the type name is missing or acceptably invalid
96 @raises L{pyxb.BadDocumentError}: if the processing type
97 configuration is L{PT_strict} and the type name fails to
98 resolve to a type definition that is consistent with any
99 provided type_class.
100 """
101 did_replace = False
102 if type_name is None:
103 return (did_replace, type_class)
104 pt = self.__processType
105 if self.PT_skip == pt:
106 return (did_replace, type_class)
107 type_en = ns_ctx.interpretQName(type_name, namespace=fallback_namespace)
108 try:
109 alternative_type_class = type_en.typeBinding()
110 except KeyError:
111 alternative_type_class = None
112 if self.PT_strict == pt:
113 if alternative_type_class is None:
114 raise pyxb.BadDocumentError('No type binding for %s' % (type_name,))
115 if (type_class is not None) and (not (type_class._IsUrType() or issubclass(alternative_type_class, type_class))):
116 raise pyxb.BadDocumentError('%s value %s is not subclass of element type %s' % (type_name, type_en, type_class._ExpandedName))
117 if (self.PT_strict == pt) or ((self.PT_lax == pt) and (alternative_type_class is not None)):
118 type_class = alternative_type_class
119 did_replace = True
120 return (did_replace, type_class)
121
135
136 -class _XML (Namespace):
137 """Extension of L{Namespace} that pre-defines components available in the
138 XML (xml) namespace. Specifically those are the attribute declarations:
139
140 - C{xml:space}
141 - C{xml:lang}
142 - C{xml:base}
143 - C{xml:id}
144
145 the encompassing attribute group declaration:
146
147 - C{xml:specialAttrs}
148
149 and the anonymous types that support these."""
150
152 """Ensure this namespace is ready for use.
153
154 Overrides base class implementation, since there is no schema
155 for this namespace. """
156
157 assert structures_module is not None
158 import pyxb.binding.datatypes as xsd
159 from pyxb.namespace import archive
160
161 self.configureCategories([archive.NamespaceArchive._AnonymousCategory()])
162
163 schema = structures_module.Schema(namespace_context=self.initialNamespaceContext(), schema_location="URN:noLocation:PyXB:XML", generation_uid=BuiltInObjectUID, _bypass_preload=True)
164
165 std_space = structures_module.SimpleTypeDefinition._CreateXMLInstance('space', schema)
166 std_space._setAnonymousName(self, anon_name='STD_ANON_space')
167 std_space._setBindingNamespace(self)
168 std_lang = structures_module.SimpleTypeDefinition._CreateXMLInstance('lang', schema)
169 std_lang._setAnonymousName(self, anon_name='STD_ANON_lang')
170 std_lang._setBindingNamespace(self)
171
172 base = schema._addNamedComponent(structures_module.AttributeDeclaration.CreateBaseInstance('base', schema, std=xsd.anyURI.SimpleTypeDefinition()))
173 id = schema._addNamedComponent(structures_module.AttributeDeclaration.CreateBaseInstance('id', schema, std=xsd.ID.SimpleTypeDefinition()))
174 space = schema._addNamedComponent(structures_module.AttributeDeclaration.CreateBaseInstance('space', schema, std=std_space))
175 lang = schema._addNamedComponent(structures_module.AttributeDeclaration.CreateBaseInstance('lang', schema, std=std_lang))
176
177 schema._addNamedComponent(structures_module.AttributeGroupDefinition.CreateBaseInstance('specialAttrs', schema, [
178 structures_module.AttributeUse.CreateBaseInstance(schema, space),
179 structures_module.AttributeUse.CreateBaseInstance(schema, base),
180 structures_module.AttributeUse.CreateBaseInstance(schema, lang),
181 structures_module.AttributeUse.CreateBaseInstance(schema, id),
182 ]))
183
184 return self
185
187 """Extension of L{Namespace} that pre-defines components available in the
188 XMLSchema namespace.
189
190 The types are defined when L{pyxb.xmlschema.structures} is imported.
191 """
192
209
210 XMLSchema_instance = _XMLSchema_instance('http://www.w3.org/2001/XMLSchema-instance',
211 description='XML Schema Instance',
212 builtin_namespace='XMLSchema_instance')
213 """Namespace and URI for the XMLSchema Instance namespace. This is always
214 built-in, and does not (cannot) have an associated schema."""
215
216 XMLNamespaces = Namespace('http://www.w3.org/2000/xmlns/',
217 description='Namespaces in XML',
218 builtin_namespace='XMLNamespaces',
219 bound_prefix='xmlns')
220 """Namespaces in XML. Not really a namespace, but is always available as C{xmlns}."""
221
222
223 XMLSchema = _XMLSchema('http://www.w3.org/2001/XMLSchema',
224 description='XML Schema',
225 builtin_namespace='XMLSchema',
226 builtin_module_path='pyxb.binding.datatypes',
227 in_scope_namespaces = { 'xs' : None })
228 """Namespace and URI for the XMLSchema namespace (often C{xs}, or C{xsd})"""
229
230
231 XHTML = Namespace('http://www.w3.org/1999/xhtml',
232 description='Family of document types that extend HTML',
233 builtin_namespace='XHTML',
234 default_namespace=XMLSchema)
235 """There really isn't a schema for this, but it's used as the default
236 namespace in the XML schema, so define it."""
237
238
239 XML = _XML('http://www.w3.org/XML/1998/namespace',
240 description='XML namespace',
241 builtin_namespace='XML',
242 builtin_module_path='pyxb.binding.xml_',
243 is_undeclared_namespace=True,
244 bound_prefix='xml',
245 default_namespace=XHTML,
246 in_scope_namespaces = { 'xs' : XMLSchema })
247 """Namespace and URI for XML itself (always available as C{xml})"""
248
249
250 XMLSchema_hfp = Namespace('http://www.w3.org/2001/XMLSchema-hasFacetAndProperty',
251 description='Facets appearing in appinfo section',
252 builtin_namespace='XMLSchema_hfp',
253 default_namespace=XMLSchema,
254 in_scope_namespaces = { 'hfp' : None
255 , 'xhtml' : XHTML })
256 """Elements appearing in appinfo elements to support data types."""
257
258
259 BuiltInNamespaces = [
260 XMLSchema_instance,
261 XMLSchema_hfp,
262 XMLSchema,
263 XMLNamespaces,
264 XML,
265 XHTML
266 ]
267
268 __InitializedBuiltinNamespaces = False
269
281
282
283 _UndeclaredNamespaceMap = { }
284 [ _UndeclaredNamespaceMap.setdefault(_ns.boundPrefix(), _ns) for _ns in BuiltInNamespaces if _ns.isUndeclaredNamespace() ]
285