@@ -192,8 +192,14 @@ from pydantic import conint, HttpUrl
192192
193193from pydantic_xml import BaseXmlModel, attr, element, wrapped
194194
195+ NSMAP = {
196+ ' co' : ' http://www.test.com/contact' ,
197+ ' hq' : ' http://www.test.com/hq' ,
198+ ' pd' : ' http://www.test.com/prod' ,
199+ }
200+
195201
196- class Headquarters (BaseXmlModel , ns = ' hq' , nsmap = { ' hq ' : ' http://www.test.com/hq ' } ):
202+ class Headquarters (BaseXmlModel , ns = ' hq' , nsmap = NSMAP ):
197203 country: str = element()
198204 state: str = element()
199205 city: str = element()
@@ -209,12 +215,12 @@ class Industries(BaseXmlModel):
209215 __root__: Set[str ] = element(tag = ' Industry' )
210216
211217
212- class Social (BaseXmlModel , ns_attrs = True , inherit_ns = True ):
218+ class Social (BaseXmlModel , ns_attrs = True , ns = ' co ' , nsmap = NSMAP ):
213219 type : str = attr()
214220 url: str
215221
216222
217- class Product (BaseXmlModel , ns_attrs = True , inherit_ns = True ):
223+ class Product (BaseXmlModel , ns_attrs = True , ns = ' pd ' , nsmap = NSMAP ):
218224 status: Literal[' running' , ' development' ] = attr()
219225 launched: Optional[int ] = attr()
220226 title: str
@@ -236,7 +242,7 @@ class COO(Person):
236242 position: Literal[' COO' ] = attr()
237243
238244
239- class Company (BaseXmlModel , tag = ' Company' , nsmap = { ' pd ' : ' http://www.test.com/prod ' } ):
245+ class Company (BaseXmlModel , tag = ' Company' , nsmap = NSMAP ):
240246 class CompanyType (str , Enum ):
241247 PRIVATE = ' Private'
242248 PUBLIC = ' Public'
@@ -254,9 +260,9 @@ class Company(BaseXmlModel, tag='Company', nsmap={'pd': 'http://www.test.com/pro
254260 headquarters: Headquarters
255261 socials: List[Social] = wrapped(
256262 ' contacts/socials' ,
257- element(tag = ' social' , default_factory = set ),
263+ element(tag = ' social' , default_factory = list ),
258264 ns = ' co' ,
259- nsmap = { ' co ' : ' http://www.test.com/contact ' }
265+ nsmap = NSMAP ,
260266 )
261267
262268 products: Tuple[Product, ... ] = element(tag = ' product' , ns = ' pd' )
@@ -428,6 +434,108 @@ print(request.json(indent=4))
428434```
429435
430436
437+ ### Self-referencing models:
438+
439+ ` pydantic ` library supports [ self-referencing models] ( https://pydantic-docs.helpmanual.io/usage/postponed_annotations/#self-referencing-models ) .
440+ ` pydantic-xml ` supports it either.
441+
442+ * request.xml:*
443+
444+ ``` xml
445+ <Directory Name =" root" Mode =" rwxr-xr-x" >
446+ <Directory Name =" etc" Mode =" rwxr-xr-x" >
447+ <File Name =" passwd" Mode =" -rw-r--r--" />
448+ <File Name =" hosts" Mode =" -rw-r--r--" />
449+ <Directory Name =" ssh" Mode =" rwxr-xr-x" />
450+ </Directory >
451+ <Directory Name =" bin" Mode =" rwxr-xr-x" />
452+ <Directory Name =" usr" Mode =" rwxr-xr-x" >
453+ <Directory Name =" bin" Mode =" rwxr-xr-x" />
454+ </Directory >
455+ </Directory >
456+ ```
457+
458+ * main.py:*
459+
460+ ``` python
461+ from typing import List, Optional
462+
463+ import pydantic_xml as pxml
464+
465+
466+ class File (pxml .BaseXmlModel , tag = " File" ):
467+ name: str = pxml.attr(name = ' Name' )
468+ mode: str = pxml.attr(name = ' Mode' )
469+
470+
471+ class Directory (pxml .BaseXmlModel , tag = " Directory" ):
472+ name: str = pxml.attr(name = ' Name' )
473+ mode: str = pxml.attr(name = ' Mode' )
474+ dirs: Optional[List[' Directory' ]] = pxml.element(tag = ' Directory' )
475+ files: Optional[List[File]] = pxml.element(tag = ' File' , default_factory = list )
476+
477+
478+ with open (' request.xml' ) as file :
479+ xml = file .read()
480+
481+ root = Directory.from_xml(xml)
482+ print (root.json(indent = 4 ))
483+
484+ ```
485+
486+ * output:*
487+
488+ ``` json
489+ {
490+ "name" : " root" ,
491+ "mode" : " rwxr-xr-x" ,
492+ "dirs" : [
493+ {
494+ "name" : " etc" ,
495+ "mode" : " rwxr-xr-x" ,
496+ "dirs" : [
497+ {
498+ "name" : " ssh" ,
499+ "mode" : " rwxr-xr-x" ,
500+ "dirs" : [],
501+ "files" : []
502+ }
503+ ],
504+ "files" : [
505+ {
506+ "name" : " passwd" ,
507+ "mode" : " -rw-r--r--"
508+ },
509+ {
510+ "name" : " hosts" ,
511+ "mode" : " -rw-r--r--"
512+ }
513+ ]
514+ },
515+ {
516+ "name" : " bin" ,
517+ "mode" : " rwxr-xr-x" ,
518+ "dirs" : [],
519+ "files" : []
520+ },
521+ {
522+ "name" : " usr" ,
523+ "mode" : " rwxr-xr-x" ,
524+ "dirs" : [
525+ {
526+ "name" : " bin" ,
527+ "mode" : " rwxr-xr-x" ,
528+ "dirs" : [],
529+ "files" : []
530+ }
531+ ],
532+ "files" : []
533+ }
534+ ],
535+ "files" : []
536+ }
537+ ```
538+
431539### JSON
432540
433541Since ` pydantic ` supports json serialization, ` pydantic-xml ` could be used as xml-to-json transcoder:
0 commit comments