Skip to content
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

Subtitutiongroups cause more attributes than may be serialised #735

Closed
skinkie opened this issue Dec 23, 2022 · 5 comments · Fixed by #786
Closed

Subtitutiongroups cause more attributes than may be serialised #735

skinkie opened this issue Dec 23, 2022 · 5 comments · Fixed by #786

Comments

@skinkie
Copy link
Contributor

skinkie commented Dec 23, 2022

SubstitutionGroups in xsData cause multiple attributes. Each of these attributes typically match with a type, allowing static typing. The problem appears when multiple of these attributes are filled in and the schema has a limitation, for example the element has a maxOccurs=1 (default), providing multiple variants will cause the serialised document to be invalid.

I would propose an export serialisation option (configurable) that would explicitly limit the exported attribute to the first set.

@skinkie
Copy link
Contributor Author

skinkie commented Dec 23, 2022

The following example creates a document that has a ServiceJourneyPatternRef and ServiceJourneyRef where only one of this type are allowed (in the current schema).

from xsdata.formats.dataclass.serializers import XmlSerializer
from xsdata.formats.dataclass.serializers.config import SerializerConfig
from xsdata.models.datatype import XmlDateTime
import datetime

from netex import GeneralFrame, GeneralFrameMembersRelStructure, \
    ServiceJourneyPattern, PointsInJourneyPatternRelStructure, StopPointInJourneyPattern, ScheduledStopPointRef, \
    PublicationDelivery, DataObjectsRelStructure, ScheduledStopPoint, MultilingualString, ServiceJourneyPatternRef, \
    ServiceJourney, ServiceJourneyRef

serializer_config = SerializerConfig(ignore_default_attributes=True)
serializer_config.pretty_print = True
serializer = XmlSerializer(serializer_config)

ns_map = {'': 'http://www.netex.org.uk/netex', 'gml': 'http://www.opengis.net/gml/3.2'}

with open('/tmp/out.xml', 'w') as out:
    ssp1 = ScheduledStopPoint(id="SSP1", version="1", name=MultilingualString(value="SSP1"))
    ssp2 = ScheduledStopPoint(id="SSP2", version="1", name=MultilingualString(value="SSP2"))

    sj = ServiceJourney(id="SJ", version="1")

    sjp = ServiceJourneyPattern(id="SJP", version="1", points_in_sequence=
                                PointsInJourneyPatternRelStructure(point_in_journey_pattern_or_stop_point_in_journey_pattern_or_timing_point_in_journey_pattern=
                                                                   [StopPointInJourneyPattern(id="SPIJP1", version="1", order=1,
                                                                                              scheduled_stop_point_ref=ScheduledStopPointRef(ref="SSP1", version="1"),
                                                                                              service_journey_pattern_ref=ServiceJourneyPatternRef(ref="SJP", version="1"),
                                                                                              service_journey_ref=ServiceJourneyRef(ref="SJ", version="1")
                                                                                              ),
                                                                    StopPointInJourneyPattern(id="SPIJP2", version="1", order=2, scheduled_stop_point_ref=ScheduledStopPointRef(ref="SSP2", version="1"))]))

    general_frame = GeneralFrame(id="GF", version="1", members=GeneralFrameMembersRelStructure(choice=[ssp1, ssp2, sj, sjp]))

    publication_delivery = PublicationDelivery(
        publication_timestamp=XmlDateTime.from_datetime(datetime.datetime.now()))
    publication_delivery.version = "ntx:1.1"
    publication_delivery.participant_ref = "NDOV"
    publication_delivery.description = "NeTEx export"
    publication_delivery.data_objects = DataObjectsRelStructure(choice=[general_frame])

    serializer.write(out, publication_delivery, ns_map)

@tefra
Copy link
Owner

tefra commented Dec 24, 2022

Hey @skinkie, effectively substitution groups are like choices, hrm ok make sense
https://www.w3.org/TR/xmlschema-1/#key-equivalenceClass

I think we can generate them then as compound fields, then
https://xsdata.readthedocs.io/en/latest/examples/compound-fields.html

@tefra
Copy link
Owner

tefra commented Mar 28, 2023

This one is a really tough cookie, I am trying to resolve it for weeks now, that's why I am delaying the new release...

@tefra
Copy link
Owner

tefra commented May 14, 2023

I don't have a lot of free time lately, but this ticket really took a lot to fix, give it a try @skinkie

I had to rewrite how we calculate sequential fields, compound fields and min/max occurs within nested containers before I could even apply the fix to treat substitutions as choice elements.

Hopefully the result is a lot, a lot more accurate now 😄

@skinkie
Copy link
Contributor Author

skinkie commented May 14, 2023

@tefra looking forward to compare the generated code :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants