15
15
from colour_clf_io .elements import Info
16
16
from colour_clf_io .errors import ParsingError
17
17
from colour_clf_io .parsing import (
18
- NAMESPACE_NAME ,
18
+ Namespaces ,
19
19
ParserConfig ,
20
+ UnknownNamespace ,
20
21
check_none ,
22
+ detect_namespace ,
21
23
element_as_text ,
22
24
elements_as_text_list ,
23
25
set_attr_if_not_none ,
@@ -66,10 +68,10 @@ class ProcessList:
66
68
- https://docs.acescentral.com/specifications/clf/#processList
67
69
"""
68
70
69
- id : str
71
+ id : str | None
70
72
"""A string to serve as a unique identifier of the *ProcessList*."""
71
73
72
- compatible_CLF_version : str
74
+ compatible_CLF_version : str | None
73
75
"""
74
76
A string indicating the minimum compatible CLF specification version
75
77
required to read this file. The compCLFversion corresponding to this
@@ -123,10 +125,10 @@ class ProcessList:
123
125
def from_xml (xml : lxml .etree ._Element | None ) -> ProcessList | None :
124
126
"""
125
127
Parse and return a :class:`colour_clf_io.ProcessList` class instance
126
- from the given XML element. Returns `None`` if the given XML element is
128
+ from the given XML element. Returns `` None`` if the given XML element is
127
129
``None``.
128
130
129
- Expects the XML element to be a valid element according to the *CLF*
131
+ Expects the XML element to be a valid element, according to the *CLF*
130
132
specification.
131
133
132
134
Parameters
@@ -150,6 +152,27 @@ def from_xml(xml: lxml.etree._Element | None) -> ProcessList | None:
150
152
if xml is None :
151
153
return None
152
154
155
+ detected_namespace = detect_namespace (xml )
156
+ document_namespace : Namespaces | None = None
157
+ match detected_namespace :
158
+ case None :
159
+ document_namespace = None
160
+ case UnknownNamespace (value ):
161
+ exception = f"Found invalid xmlns attribute in *ProcessList*: { value } "
162
+ raise ParsingError (exception )
163
+ case Namespaces ():
164
+ document_namespace = detected_namespace
165
+
166
+ if document_namespace == Namespaces .SMTP :
167
+ error = (
168
+ "SMPTE ST 2136-1 files are not fully supported. See "
169
+ "https://github.com/colour-science/colour-clf-io/issues/6 "
170
+ "for more information. "
171
+ )
172
+ raise ParsingError (error )
173
+
174
+ config = ParserConfig (namespace = document_namespace )
175
+
153
176
id_ = xml .get ("id" )
154
177
check_none (id_ , "ProcessList must contain an `id` attribute" )
155
178
@@ -159,18 +182,6 @@ def from_xml(xml: lxml.etree._Element | None) -> ProcessList | None:
159
182
'ProcessList must contain a "compCLFversion" attribute' ,
160
183
)
161
184
162
- # By default, we would expect the correct namespace as per the specification.
163
- # But if it is not present, we will still try to parse the document anyway.
164
- # We won't accept a wrong namespace through.
165
- config = ParserConfig ()
166
- namespace = xml .xpath ("namespace-uri(.)" )
167
- if not namespace :
168
- config .namespace_name = None
169
- elif namespace != config .namespace_name :
170
- exception = f"Found invalid xmlns attribute in *ProcessList*: { namespace } "
171
-
172
- raise ParsingError (exception )
173
-
174
185
name = xml .get ("name" )
175
186
inverse_of = xml .get ("inverseOf" )
176
187
info = Info .from_xml (xml , config )
@@ -193,8 +204,8 @@ def from_xml(xml: lxml.etree._Element | None) -> ProcessList | None:
193
204
assert_bit_depth_compatibility (process_nodes )
194
205
195
206
return ProcessList (
196
- id = id_ , # pyright: ignore
197
- compatible_CLF_version = compatible_clf_version , # pyright: ignore
207
+ id = id_ ,
208
+ compatible_CLF_version = compatible_clf_version ,
198
209
process_nodes = process_nodes ,
199
210
name = name ,
200
211
inverse_of = inverse_of ,
@@ -204,17 +215,27 @@ def from_xml(xml: lxml.etree._Element | None) -> ProcessList | None:
204
215
description = description ,
205
216
)
206
217
207
- def to_xml (self ) -> lxml .etree ._Element :
218
+ def to_xml (self , name_space : Namespaces = Namespaces . AMPAS ) -> lxml .etree ._Element :
208
219
"""
209
220
Serialise this object as an XML object.
210
221
222
+ Parameters
223
+ ----------
224
+ name_space
225
+ :class:`colour_clf_io.Namespaces` instance to be used for the namespace
226
+ of the document.
227
+
211
228
Returns
212
229
-------
213
230
:class:`lxml.etree._Element`
214
231
"""
215
232
xml = lxml .etree .Element ("ProcessList" )
216
233
217
- xml .set ("xmlns" , NAMESPACE_NAME )
234
+ xml .set ("xmlns" , name_space .value )
235
+
236
+ for description_text in self .description :
237
+ description_element = lxml .etree .SubElement (xml , "Description" )
238
+ description_element .text = description_text
218
239
219
240
set_attr_if_not_none (xml , "id" , self .id )
220
241
set_attr_if_not_none (xml , "compCLFversion" , self .compatible_CLF_version )
@@ -225,11 +246,7 @@ def to_xml(self) -> lxml.etree._Element:
225
246
226
247
if self .info :
227
248
xml .append (self .info .to_xml ())
228
- for description_text in self .description :
229
- description_element = lxml .etree .SubElement (xml , "Description" )
230
- description_element .text = description_text
231
- # TODO: we might have to store a single list of children in order to preserve
232
- # ordering of description and process nodes
249
+
233
250
for process_node in self .process_nodes :
234
251
xml .append (process_node .to_xml ())
235
252
return xml
0 commit comments