@@ -277,6 +277,68 @@ Field specification syntax is similar to ``pydantic`` one. For more information
277277see the `documentation <https://docs.pydantic.dev/latest/concepts/models/#dynamic-model-creation >`_.
278278
279279
280+ Document type declaration
281+ ~~~~~~~~~~~~~~~~~~~~~~~~~
282+
283+ A document type declaration is an instruction that associates a particular XML document
284+ with a document type definition (DTD).
285+
286+ DTD is supported by ``lxml `` backend only so the library doesn't provide an api for that natively,
287+ but it can be easily implemented by your hand:
288+
289+ .. code-block :: python
290+
291+ from typing import Any, ClassVar, Union
292+
293+ import pydantic_xml as pxml
294+ import lxml.etree
295+
296+
297+ class DTDXmlModel (pxml .BaseXmlModel ):
298+ DOC_PUBLIC_ID : ClassVar[str ]
299+ DOC_SYSTEM_URL : ClassVar[str ]
300+
301+ def to_xml (
302+ self ,
303+ * ,
304+ skip_empty : bool = False ,
305+ exclude_none : bool = False ,
306+ exclude_unset : bool = False ,
307+ ** kwargs : Any,
308+ ) -> Union[str , bytes ]:
309+ root = self .to_xml_tree(skip_empty = skip_empty, exclude_none = exclude_none, exclude_unset = exclude_unset)
310+ tree = lxml.etree.ElementTree(root)
311+ tree.docinfo.public_id = self .DOC_PUBLIC_ID
312+ tree.docinfo.system_url = self .DOC_SYSTEM_URL
313+
314+ return lxml.etree.tostring(tree, ** kwargs)
315+
316+
317+ class Html (DTDXmlModel , tag = ' html' ):
318+ DOC_PUBLIC_ID : ClassVar[str ] = ' -//W3C//DTD HTML 4.01//EN'
319+ DOC_SYSTEM_URL : ClassVar[str ] = ' http://www.w3.org/TR/html4/strict.dtd'
320+
321+ title: str = pxml.wrapped(' head' , pxml.element())
322+ body: str = pxml.element()
323+
324+
325+ html_doc = Html(title = " This is a title" , body = " Hello world!" )
326+ xml = html_doc.to_xml(pretty_print = True )
327+
328+ print (xml.decode())
329+
330+
331+ .. code-block :: xml
332+
333+ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
334+ <html >
335+ <head >
336+ <title >This is a title</title >
337+ </head >
338+ <body >Hello world!</body >
339+ </html >
340+
341+
280342 Mypy
281343~~~~
282344
0 commit comments