@@ -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