Models¶
Dataclasses is the default output format for the code generator and ships with its own modules for xml and json marshalling. The generated models are simple python dataclasses with some optional metadata to control how the data structures are transferred during data binding.
If you are working with xml documents that don’t have any schema definition you can create these models manually.
Basic Model¶
@dataclass
class Currency:
id: int = field(metadata=dict(type="Attribute", name="ID"))
name: str = field(metadata=dict(type="Attribute", name="Name"))
num_code: int = field(metadata=dict(name="NumCode"))
iso_code: str = field(metadata=dict(name="CharCode"))
nominal: int = field(metadata=dict(name="Nominal"))
value: Decimal = field(metadata=dict(name="Value"))
@dataclass
class Currencies:
class Meta:
name = "ValCurs"
date: str = field(metadata=dict(type="Attribute", name="Date"))
name: str = field(metadata=dict(type="Attribute"))
values: List[Currency] = field(default_factory=list, metadata=dict(name="Valute"))
<ValCurs Date="19.04.2020" name="Official exchange rate">
<Valute ID="47">
<NumCode>978</NumCode>
<CharCode>EUR</CharCode>
<Nominal>1</Nominal>
<Name>Euro</Name>
<Value>19.2743</Value>
</Valute>
<Valute ID="44">
<NumCode>840</NumCode>
<CharCode>USD</CharCode>
<Nominal>1</Nominal>
<Name>US Dollar</Name>
<Value>17.7177</Value>
</Valute>
</ValCurs>
Class Meta¶
Property |
Type |
Description |
---|---|---|
name |
str |
The real name of the element this class represents. |
nillable |
bool |
Specifies whether an explicit empty value can be assigned, default: False |
namespace |
str |
The element xml namespace. |
Field Typing¶
Simply follow the Python lib dataclasses documentation.
Field Metadata¶
Property |
Type |
Description |
---|---|---|
name |
str |
The real name of the element or attribute this field represents. |
type |
str |
The field xml type:
|
nillable |
bool |
Specifies whether an explicit empty value can be assigned. |
mixed |
bool |
Specifies whether the field supports mixed content. (1) |
sequential |
bool |
Specifies whether the field value(s) must appear in sequence with other
sequential sibling fields. eg |
tokens |
bool |
Use a list to map simple values. eg |
namespace |
str |
Specifies the field xml namespace. (2) |
The code generator adds also the field restrictions like minLength or required flag but currently they are only used to troubleshoot the code generator.
- 1
Mixed content must be combined
Wildcard
fields with typeList[object]
. w3schools- 2
It’s a common practice in schema definitions to require elements to be qualified and attributes to be unqualified.
Element
fields with an omitted namespace inherit the namespace from the parent class/element andAttribute
fields don’t.If you need to break the namespace inheritance for
Element
fields set the namespace to an empty stringnamespace=""
.
Type: Element¶
This type represents a traditional xml element and can be the building block and container for other elements, attributes, text or any combination of them.
annotation: List[Annotation] = field(
default_factory=list,
metadata={
"name": "annotation",
"type": "Element",
"namespace": "http://www.w3.org/XML/2004/xml-schema-test-suite/",
)
)
<annotation xmlns="http://www.w3.org/2001/XMLSchema">...</annotation>
<annotation xmlns="http://www.w3.org/2001/XMLSchema">...</annotation>
<annotation xmlns="http://www.w3.org/2001/XMLSchema">...</annotation>
...
Type: Elements¶
This type represents repeating xs:choice elements. It’s a compound list field for elements and wildcards that can be used to preserve elements ordering between data marshalling.
node_or_id_or_idref: List[object] = field(
default_factory=list,
metadata={
"type": "Elements",
"choices": (
{
"name": "node",
"type": Type["Node"],
},
{
"name": "e1",
"type": str,
"nillable": True,
},
{
"name": "e2",
"type": int,
"namespace": "xsdata",
},
),
}
)
<e1 xmlns="xsdata">a</e1>
<e1 xmlns="xsdata">b</e1>
<e2 xmlns="xsdata">1</e1>
<e1 xmlns="xsdata">c</e1>
<e2 xmlns="xsdata">2</e1>
...
Choice Metadata
Property |
Type |
Description |
---|---|---|
name |
str |
The real name of the element this choice represents. |
type |
str |
The field type hint. |
nillable |
bool |
Specifies whether an explicit empty value can be assigned. |
wildcard |
bool |
Specifies whether this is a |
tokens |
bool |
Use a list to map simple values. eg |
namespace |
str |
Specifies the field xml namespace. |
Warning
Compound fields preserve elements ordering but instead the direct element name association is lost during marshalling. If the choices include multiple elements with the same type then it’s actually impossible to map correctly values to elements.
For that reason the xml parser will use the generic class
DerivedElement
to wrap values
in order to maintain the original qualified name as well.
If your compound field includes only unique types and you are working with a dataclass instance manually you can skip the usage of the wrapper as the xml serializer will try to match a type to a choice as well.
obj.node_or_id_or_idref.extend(("a", "b", 1, "c", "2"))
Type: Attribute¶
This type represents a traditional xml attribute.
language: Optional[str] = field(
default=None,
metadata={
"name": "lang",
"type": "Attribute",
"namespace": "http://www.w3.org/XML/1998/namespace"
}
)
<root xmlns:xml="http://www.w3.org/XML/1998/namespace" xml:lang="en">
Type: Wildcard¶
This type represents xs:any
elements or elements with type xs:AnyType
.
Wildcards can have a normal uri namespace or use one of xml schema generics.
Namespace |
Description |
---|---|
##any |
element from any namespace is allowed |
##other |
element from any namespace other than the parent’s namespace |
##local |
element must come from no namespace |
##targetNamespace |
element from the namespace of the parent can be present |
any_element: List[object] = field(
default_factory=list,
metadata={
"type": "Wildcard",
"namespace": "##any",
}
)
This type of field accepts any primitive value or an another dataclass instance or a
generic AnyElement
instance.
Type: Attributes¶
This type represents xs:anyAttribute
elements. It needs to be defined as
a dictionary of. The wildcard namespace features also apply.
any_attributes: Dict = field(
default_factory=dict,
metadata={
"type": "Attributes",
"namespace": "##other"
}
)
Type: Text¶
This is the default field type and represents any atomic value. The value of this field is directly assigned as text to elements.
@dataclass
class Root:
class Meta:
name = "root"
value: Optional[int] = field(default=None)
<root>2020</root>