-
-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to choose an element of a choice having the same target enumeration? #913
Comments
It does sort of, kinda :) in these cases where it's impossible to derive the element because the value type is ambiguous, the parser is using derived elements <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="root">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="FuelType" type="FuelTypeEnumeration"/>
<xsd:element name="TypeOfFuel" type="FuelTypeEnumeration"/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
<xsd:simpleType name="FuelTypeEnumeration">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="a"/>
<xsd:enumeration value="b"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema> xml = """
<root>
<FuelType>a</FuelType>
<TypeOfFuel>b</TypeOfFuel>
</root>
"""
parser = XmlParser()
res = parser.from_string(xml)
print(res)
>>> Root(fuel_type_or_type_of_fuel=[<FuelTypeEnumeration.A: 'a'>, DerivedElement(qname='TypeOfFuel', value=<FuelTypeEnumeration.B: 'b'>, type=None)]) |
Of course serialization with the derived element wrapper works as expected |
So for serialisation you would need to use DerivedElement? |
Yes |
@tefra considering the one below. The choice has different target types, but the only way to differentiate between is using the type but not anything related to an element name - or so it seems. @dataclass(kw_only=True)
class AboAnfrageType:
choice: List[
Union[
AboAsbrefType,
AboAsbtype,
AboAzbrefType,
AboAzbtype,
AboVistype,
AboAndtype,
AboAusrefType,
AboAustype,
int,
bool,
]
] = field(
default_factory=list,
metadata={
"type": "Elements",
"choices": (
{
"name": "AboASBRef",
"type": AboAsbrefType,
"namespace": "",
},
{
"name": "AboASB",
"type": AboAsbtype,
"namespace": "",
},
{
"name": "AboAZBRef",
"type": AboAzbrefType,
"namespace": "",
},
{
"name": "AboAZB",
"type": AboAzbtype,
"namespace": "",
},
{
"name": "AboVIS",
"type": AboVistype,
"namespace": "",
},
{
"name": "AboAND",
"type": AboAndtype,
"namespace": "",
},
{
"name": "AboAUSRef",
"type": AboAusrefType,
"namespace": "",
},
{
"name": "AboAUS",
"type": AboAustype,
"namespace": "",
},
{
"name": "AboLoeschen",
"type": int,
"namespace": "",
},
{
"name": "AboLoeschenAlle",
"type": bool,
"namespace": "",
},
),
},
)
sender: str = field(
metadata={
"name": "Sender",
"type": "Attribute",
"required": True,
}
)
zst: XmlDateTime = field(
metadata={
"name": "Zst",
"type": "Attribute",
"required": True,
}
) |
I am not sure I follow @skinkie |
Consider the schema below. xsData gives me a List of different types, int or boolean for the choice element. If I want to know if if isinstance(abo_anfrage_type.choice, bool):
await abo_loeschen_alle(abo_anfrage_type.sender)
antwort = AboAntwortType(bestaetigung=BestaetigungType(fehlernummer="0", ergebnis=ErgebnisType.OK, zst=XmlDateTime.now()))
elif isinstance(abo_anfrage_type.choice, int):
await abo_loeschen(abo_anfrage_type.sender, abo_anfrage_type.choice)
antwort = AboAntwortType(bestaetigung=BestaetigungType(fehlernummer="0", ergebnis=ErgebnisType.OK, zst=XmlDateTime.now()))
elif isinstance(abo_anfrage_type.choice, list):
abo_aus_types = [abo_aus_type for abo_aus_type in abo_anfrage_type.choice if isinstance(abo_aus_type, AboAustype)]
for abo_aus_type in abo_aus_types:
await abo_aus(abo_anfrage_type.sender, abo_aus_type) <xsd:element name="AboAnfrage" type="AboAnfrageType"/>
<xsd:complexType name="AboAnfrageType">
<xsd:choice>
<xsd:group ref="AboGroup"/>
<xsd:choice>
<xsd:element name="AboLoeschen" type="AboIDType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="AboLoeschenAlle" type="xsd:boolean" minOccurs="0"/>
</xsd:choice>
</xsd:choice>
<xsd:attribute name="Sender" type="SenderType" use="required"/>
<xsd:attribute name="Zst" type="xsd:dateTime" use="required"/>
</xsd:complexType>
<xsd:group name="AboGroup">
<xsd:choice>
<xsd:element name="AboASBRef" type="AboASBRefType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="AboASB" type="AboASBType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="AboAZBRef" type="AboAZBRefType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="AboAZB" type="AboAZBType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="AboVIS" type="AboVISType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="AboAND" type="AboANDType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="AboAUSRef" type="AboAUSRefType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="AboAUS" type="AboAUSType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:choice>
</xsd:group> |
That's the case of all union dataclasses fields, you have to check the instance of the value before you process it. |
I don't know what the best option would be. Obviously it could be convinient to have something like choice.AboASBRef, but I don't know how feasible such interface would be especially with an ordered list. |
Let's continue here #920, easier examples... |
Very pretty example of something that xsData can't handle, or can it?
The text was updated successfully, but these errors were encountered: