In het onlangs verschenen rapport “20150925_Eindrapport_DenHaag_StUF_standaard.pdf” (Analyse van de StUF-BG 3.10 standaard), dat de Software Improvement Group in opdracht van de gemeente Den Haag heeft opgesteld, wordt onder andere het gebruik van de nillable=”true” constructie in de StUF 3.01 standaard aan de kaak gesteld. Ruwweg gesproken heeft deze constructie van XML Schema twee nadelen:
- Standaard tooling zoals die van Microsoft .NET en Java hebben moeite met deze constructie. Dit leidt bijvoorbeeld tot allerlei problemen en work-arounds bij codegeneratie.
- De combinatie van het gebruik van minOccurs=”0” en nillable=”true” maakt StUF een complexe standaard.
In deze notitie (zie bijlage) wordt een voorstel gedaan om de schema’s van de nieuwe StUF 3.02 standaard op een andere manier in te richten zodat de nillable-constructie niet meer nodig is. Het nieuwe voorgestelde schema heeft bovendien als voordeel dat het afdwingt dat verplichte elementen altijd voorzien zijn van een noValue waarde indien ze zelf geen inhoud hebben.
Bijgaand (zie bijlage) het rapport van gemeente Den Haag dat de aanleiding was van bovenstaande RFC. Het is naar mijn mening een goed genuanceerd rapport geworden met aanbevelingen die wat mij betreft doorgevoerd kunnen worden in StUF 3.02. Bovenstaande RFC is daar het eerste resultaat van; er zullen hoogst waarschijnlijk nog meer RFC's volgen. In de aankomende StUF Expertgroep zal er een extra agendapunt worden ingelast om hier verder bij stil te staan.
Bijlage
20150925_Eindrapport_DenHaag_StUF_standaard.pdfDit RFC is opgevoerd in de onderhoudsverzoeken als RFC0413.
De lijst met onderhoudsverzoeken vind je op:
gemmaonline.nl/index.php/StUF-Expertgroep#Documenten
Kunnen we het element 'noValue' in dit voorstel nog een Nederlandstalige naam geven (bijv. 'leeg' of 'leegElement') of ligt dat lastig i.v.m. het stelselstandaardisatietraject?
Voortschrijdend inzicht heeft mij ingegeven om de attributes toch maar niet te verbieden XML-berichten. Anders worden de berichten te groot, slecht leesbaar en bovenal niet representatief voor een elegante syntax. De vormgeving van de berichten is toch het gezicht of het visitekaartje van de standaard. Gelukkig kunnen we in stuf0302 het gebruik van xsi:nil="true" (nillable) eenvoudig omzeilen door de volgende constructie te gebruiken:
<BG:object StUF:entiteittype=”NPS”>
<BG:inp.bsn waarde=”123456789”/>
<BG:voornamen waarde=”Henri Peter”/>
<BG:voorvoegselGeslachtsnaam StUF:noValue=”geenWaarde”/>
<BG:geslachtsnaam waarde=”Korver”/>
</BG:object>
Er is een nieuw attribute "waarde" toegevoegd waarin de waarde van het element wordt opgenomen. Indien een element geen waarde heeft kun je het attribute "waarde" eenvoudig weglaten zoals we zien in het element "BG:voorvoegselGeslachtsnaam".
In de huidige 0301-situatie zijn we veroordeeld tot het gebruik van xsi:nil="true" bij elementen die geen lege strings kunnen bevatten. Bijvoorbeeld de grootte van een huishouden bestaat altijd uit 2 cijfers.
<BG:object entiteittype=”HHD”>
<BG:grootte>02</BG:grootte>
</BG:object>
<BG:object entiteittype=”HHD”>
<BG:grootte StUF:noValue=”waardeOnbekend” xsi:nil="true"/>
</BG:object>
In de 0302-situatie ziet het er dan zo uit:
<BG:object entiteittype=”HHD”>
<BG:grootte waarde=”02"/>
</BG:object>
<BG:object entiteittype=”HHD”>
<BG:grootte StUF:noValue=”waardeOnbekend"/>
</BG:object>
Een ander alternatief om het gebruik van xsi:nil="true" te omzeilen is het toevoegen van lege waarden aan het waardenbereik van een element. Dit kan door simpleType’s uit te breiden met een lege string. Hieronder een voorbeeld:
<xs:simpleType name="Geslachtsaanduiding">
<xs:restriction base="xs:string">
<xs:enumeration value="M"/>
<xs:enumeration value="V"/>
<xs:enumeration value="O"/>
<xs:enumeration value=""/>
</xs:restriction>
</xs:simpleType>
Datatypen (zoals Integers) die van zich zelf geen lege waarden bevatten kunnen uitgebreid worden met een lege string door gebruik van de xs:union-constructie:
<xs:simpleType name="Integer-e">
<xs:union memberTypes="xs:integer LegeString"/>
</xs:simpleType>
<xs:simpleType name="LegeString">
<xs:restriction base="xs:string">
<xs:enumeration value=""/>
</xs:restriction>
</xs:simpleType>
Helaas heeft het gebruik van unions ook een keerzijde. De codegenerator .NET omgeving zet alle simpleType’s met een union (dus ook xs:date, xs:integer, etc.) om naar het standaard datatype string, zie
https://msdn.microsoft.com/en-us/library/bc57azyw(VS.85).aspx
Op zich wordt er wel correcte en bruikbare code gegenereerd, wat dat betreft een absolute verbetering in vergelijking met het gebruik van xsi:nil=”true”, maar het is jammer dat de gegenereerde code niet altijd meer refereert naar de originele datatypes waardoor de ontwikkelaar iets meer handwerk zal moeten verrichten.
Tenslotte is er nog een andere optie om het nillable-probleem op te lossen: dummy waarden toelaten in de inhoud van een element indien het waardenbereik niet leeg kan zijn. Bijv.
<leeftijd StUF:noValue=”geenWaarde”>999</leeftijd>
In geval van de aanwezigheid van het attribute StUF:noValue zal de inhoud van het element dus genegeerd moeten worden. Eenzelfde constructie gebruiken we nu ook bij datums en tijdstippen. Daar moet je ook altijd een dummy waarde opnemen.
Deze constructie met dummy waarden hoef je gelukkig maar op een klein aantal plekken toe te passen, alleen de elementen die natuurlijkerwijs geen lege strings bevatten zoals getallen en datums. Bij de vaker voorkomende enumeraties kunnen we zonder de xs:union-contructie eenvoudig een lege string aan het simpleType toevoegen d.m.v. een extra <xs:enumeration value=""/> element zoals het eerste voorbeeld bovenaan deze post.
Tijdens de StUF Expertgroep van 18 november 2015 is gebleken dat niet voor iedereen het een uitgemaakte zaak is dat de aanwezigheid van xsi:nil een probleem oplevert bij code generatie.
Ook met de wijze waarop code generatoren omgaan met xsi:nil is niet iedereen het eens.
Tijdens de StUF Expertgroep van 16 december 2015 zijn nieuwe voorstellen gedaan teneinde xsi:nil uit te bannen.
Overigens bleek ook nu weer dat de leden van de StUF Expertgroep verschillend denken over het uitbannen van xsi:nil.
Tijdens de vergadering komen nog enkele alternatieven naar voren die verder bekeken moeten worden.
Afgesproken is dat leveranciers op het forum voorstellen doen hoe binnen de StUF standaard geen gebruik meer te maken van xsi:nil. In volgende vergadering wordt een besluit genomen
In een eerdere post vandaag werd de xs:union-constructie naar voren gebracht om het gebruik van xsi:nil=”true” te omzeilen. Deze oplossing heeft als schaduwzijde dat .NET code genereert met een zwakkere binding naar de onderliggende datatypen (string in plaats van date, integer, decimal, etc.) .
Daarom bij deze een nieuw voorstel om het netelige nillable-probleem het hoofd te bieden. Dit voorstel is een variant op de groep-constructie van het eerste voorstel (zie eerste post in deze discussie), hierbij worden groep-elementen gebruikt met daarbinnen de speciale subelementen <waarde> en <noValue>. Het verschil is nu dat we deze groep-constructie alléén toepassen bij elementen met datatypen die van zichzelf geen lege string kunnen bevatten (datums, integers, decimals). Booleans zijn een speciaal geval, daarvoor zou ik dan niet het standaard type xs:boolean gebruiken maar een eigen simpleType met een lege string:
<xs:simpleType name="Boolean>
<xs:restriction base="string">
<xs:enumeration value="true"/>
<xs:enumeration value="false"/>
<xs:enumeration value=""/>
</xs:restriction>
</xs:simpleType>
Op deze manier hoef je voor boolean-elementen geen groep-constructie te gebruiken. De veel voorkomende simpleType’s met enumeraties kunnen op eenzelfde manier eenvoudig met een lege string worden uitgebreid.
Er is ook nog extra aandacht nodig voor strings met een regular expression die de lege string niet valideert of strings met een minLength > 0. In dat geval lijkt de union het handigste, als Java generatoren ermee overweg kunnen. Alternatief is ook daar de groep-constructie te gebruiken. Het gebruik van union heeft hier in principe geen nadelige gevolgen voor zwakkere binding omdat het een union is van een lege string met een andere string en niet met een ander datatype zoals een integer.
Ergo: Je betaalt nog maar een kleine prijs voor het omzeilen van nillable="true": we hoeven de groep-constructie maar in een klein aantal gevallen te gebruiken waardoor de elegantie van StUF-syntax gehandhaafd blijft. En daar waar de “exotische” groep-constructie gebruikt wordt is er meestal toch al een speciale constructie zoals bij datums.
Nog even samenvattend, in deze discussie zijn inmiddels vijf scenario’s voor het oplossen van het netelige nillable-probleem naar voren gekomen:
Groep-constructie (zie 1.) alléén gebruiken bij elementen met datatypen die van zichzelf geen lege string kunnen bevatten (datums, integers, decimals, strings met restricties, etc.). Zie post 8.
Mijn voorkeur gaat uit naar scenario 5!
Tijdens de StUF Expertgroep van 20 januari 2016 zijn de hierboven geschetste 5 alternatieven voorgelegd. De leden van de StUF Expertgroep waren onderling verdeeld over de meest geschikte variant. Sommigen hadden een voorkeur voor 5 anderen voor 4 en weer anderen voor 1. Uiteindelijk is besloten de pilot van de gemeente Den Haag af te wachten.
In het vijfde scenario van de één na laatste post kwamen we uit op de volgende structuur:
<persoon xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<achternaam>Korver</achternaam>
<voorvoegsel StUF:noValue="geenWaarde"/>
<huisnummer>
<waarde>12</waarde>
</huisnummer>
<geboortedatum>
<noValue>waardeOnbekend</noValue>
</geboortedatum>
</persoon>
Het concept "noValue" heeft nu twee representaties: 1) als attribute 2) als element.
Dit is niet consistent. Het is eleganter als "noValue" altijd als attribute voorkomt. In geval van lege elementen die geen lege string kunnen zijn, introduceren we het element <StUF:leeg/>, zie onderstaand voorbeeld:
<persoon xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<achternaam>Korver</achternaam>
<voorvoegsel StUF:noValue="geenWaarde"/>
<huisnummer>
<waarde>12</waarde>
</huisnummer>
<geboortedatum StUF:noValue="waardeOnbekend"/>
<StUF:leeg/>
</geboortedatum>
</persoon>
Met deze constructie kunnen we ook nillables omzeilen in lege relaties. Zo dus:
<relatie StUF:entiteittype="relatie" StUF:noValue="geenWaarde">
<StUF:leeg/>
</relatie>
in plaats van
<relatie StUF:entiteittype="relatie" StUF:noValue="geenWaarde" xsi:nil="true"/>
Dit nieuwe voorstel (scenario 6) lost dus ook het probleem van de lege relaties op. Hiermee lijkt het nillable-probleem in zijn geheel getackeld te zijn. Het spreekt voor zich dat mijn voorkeur uitgaat naar scenario 6. Ik hoop dat in de aankomende StUF Expertgroep deze knoop doorgehakt wordt. Als er technische bezwaren zijn die over het hoofd zijn gezien, dan verneem ik die graag asap via dit forum.
In de laatste expertgroep-bijeenkomst is aangedragen dat het verschillend moeten behandelen van null-waarden in verschillende datatypes onwenselijk is. Voorstel nummer 6 beantwoordt ook dit bezwaar niet (volledig).
Tijdens de discussies in de expertgroep blijkt ook nog eens dat de aanwezigen niet voldoende op de hoogte zijn van de problemen. We zijn dus een oplossing aan het bedenken voor een probleem dat is aangedragen, maar kunnen niet beoordelen of een oplossing het probleem voldoende oplost, dan wel of het probleem op een eenvoudiger, dan wel nettere manier kan worden opgelost. Ik stel voor kennis bij de expertgroep te halen die bekend is met het door SIG geschetste probleem. Dit is een partij die kennis heeft van de serializers die volgens het SIG-rapport veel gebruikt worden en die de genoemde problemen ondervinden. Alleen dan kunnen we in gezamenlijk overleg bepalen wat een goede oplossing zou kunnen zijn die voor alle partijen kan werken en die zoveel mogelijk aansluit bij de onderliggende standaard (XML). Het valt me op dat in deze hele discussie schijnbaar niemand zich mengt die het probleem daadwerkelijk ondervindt.
Als dit niet lukt, dan is mijn voorstel de huidige (werkende en XML-compliant!) oplossing te handhaven. Welke oplossing we ook kiezen: het lijkt erop dat er bij codegeneratie sowieso handwerk moet worden gedaan om uitzonderingen af te kunnen handelen...
Hoi Sid, ik weet dat jij in de afgelopen expertgroep-bijeenkomst aangaf dat het verschillend moeten behandelen van null-waarden onwenselijk is. Echter ik begreep toen en begrijp nu nog steeds niet waarom dit onwenselijk is? Kun jij inhoudelijk aangeven tot wat voor concrete problemen dit leidt?
Zelfs al zouden we nillable="true" handhaven voor datatypen die van zich zelf geen lege waarden bevatten (datums, integers, decimals, etc.) dan zou ik nog steeds opteren om in de nieuwe versie van StUF de nillable="true" constructie te verwijderen bij datatypen die wel van zich zelf lege waarden kunnen bevatten (zoals een lege string, een sequence met lengte nul, een choice met 0 keuzen, etc.).
De meeste partijen die in de expertgroep zijn vertegenwoordigd hebben al een oplossing gevonden om StUF te implementeren en hebben weinig belang om zich te mengen in het probleem van codegeneratie. Dit zal meer spelen bij nieuwe spelers die zich StUF eigen willen maken. Die nieuwe toetreders zijn vaak nog geen lid van de expertgroep.
Als er nog andere obstakels zijn die codegeneratie belemmeren dan moeten die naar mijn mening ook weggenomen worden. Kun jij aangeven welke dat zijn?
Dus het zou fijn zijn als je je bezwaren met inhoudelijke en concrete argumenten zou kunnen onderbouwen.
Sid beargumenteert net dat zoals jij zelf ook terecht aangeeft de partijen die problemen ervaren met codegeneratie geen deel uitmaken van de StUF Expertgroep. Hierdoor is het voor ons moeilijk om aan te geven wat de exacte en specifieke problemen hiermee zijn, en of er wellicht nog obstakels voor codegeneratie zijn welke tot nu toe over het hoofd worden gezien. Vandaar zou die kennis gehaald kunnen worden bij een externe partij die kennis heeft van de volgens het SIG-rapport veel gebruikte serializers.
In de laatste StUF expertgroep kwam het voorstel naar voren om toch maar te kiezen voor een scenario waarbij het gebruik van de elementen ‘waarde’ en ‘leeg’ op alle elementen wordt toegepast. Oftewel een nieuw scenario 7 gebaseerd op scenario 1. Hieronder een voorbeeld van dit nieuwe scenario:
<persoon StUF:entiteittype="NPS">
<achternaam>
<waarde>Korver</waarde>
</achternaam>
<voorvoegsel StUF:noValue="geenWaarde">
<StUF:leeg/>
</voorvoegsel>
<huisnummer>
<waarde>12</waarde>
</huisnummer>
<geboortedatum StUF:noValue="waardeOnbekend">
<StUF:leeg/>
</geboortedatum>
<rps.isEigenaarVan StUF:entiteittype="NPSMAC" StUF:noValue="geenWaarde">
<StUF:leeg/>
</rps.isEigenaarVan>
</persoon>
Bij nadere bestudering van scenario 7 stuiten we op het nadeel dat het wel of niet correct aanwezig zijn van het attribute StUF:noValue niet kan worden afgedwongen door het schema. Dit kan leiden tot de volgende ongewenste XML-expressies:
<achternaam StUF:noValue="geenWaarde">
<waarde>Korver</waarde>
</achternaam>
<geboortedatum >
<StUF:leeg/>
</geboortedatum>
Deze observatie doet mij vermoeden dat scenario 1 de beste keuze is als je streeft naar een mechanisme dat uniform is voor alle elementen. Let wel op dat zowel scenario 1 als 7 de syntax van StUF gigantisch opblazen en naar mijn mening qua leesbaarheid en elegantie geen visitekaartje zijn voor StUF. Wat dat betreft blijft scenario 6 mijn absolute favoriet.
Naar aanleiding van de voorgaande reactie van Henri heb ik nog een nieuw alternatief bedacht. Een alternatief op optie 7 waarbij het attribute 'StUF:noValue' wordt gedefinieerd op het element 'StUF:leeg' en ook alleen maar op dat element. Het 'StUF:noValue' attribute wordt daarmee een verantwoording van het voorkomen van het 'StUF:leeg' element. Het hierboven door Henri geschetste voorbeeld komt er dan als volgt uit te zien:
<object StUF:entiteittype="NPS">
<achternaam>
<waarde>Korver</waarde>
</achternaam>
<voorvoegsel>
<StUF:leeg StUF:noValue="geenWaarde"/>
</voorvoegsel>
<huisnummer>
<waarde>12</waarde>
</huisnummer>
<geboortedatum>
<StUF:leeg StUF:noValue="waardeOnbekend"/>
</geboortedatum>
<rps.isEigenaarVan StUF:entiteittype="NPSMAC">
<StUF:leeg StUF:noValue="geenWaarde"/>
</rps.isEigenaarVan>
</object>
Je kunt daarbij overigens nog een stap verder gaan door te bepalen dat de default betekenis van een 'StUF:leeg' element 'geenWaarde' is. Een 'StUF:leeg' element hoeft dan dus geen 'StUF:noValue' attribute te hebben. Het volgende is het resultaat:
<object StUF:entiteittype="NPS">
<achternaam>
<waarde>Korver</waarde>
</achternaam>
<voorvoegsel>
<StUF:leeg/>
</voorvoegsel>
<huisnummer>
<waarde>12</waarde>
</huisnummer>
<geboortedatum>
<StUF:leeg StUF:noValue="waardeOnbekend"/>
</geboortedatum>
<rps.isEigenaarVan StUF:entiteittype="NPSMAC">
<StUF:leeg/>
</rps.isEigenaarVan>
</object>
Tenslotte kun je er nog voor zorgen dat in een scope element van een vraagbericht (en ook alleen maar daar) zowel geen 'waarde' als geen 'StUF:leeg' element hoeft/mag worden opgenomen. Waar we in de huidige versie van StUF een 'StUF:noValue' attribute op de elementen moeten opnemen is dat in de nieuwe versie met deze optie niet nodig waardoor de scope beperkt kan blijven tot het volgende:
<scope>
<object StUF:entiteittype="NPS">
<achternaam/>
<voorvoegsel/>
<huisnummer/>
<geboortedatum/>
<rps.isEigenaarVan>
...
</rps.isEigenaarVan>
</object>
</scope>
Tijdens de StUF Expertgroep van 16 maart 2016 is besloten het laatste voorstel van Robert goed te keuren met uitzondering van het deel over de default waarde. Sid gaf nl. aan dat eerder is besproken om bij attributen geen default waarde te gebruiken. Voorwaarde is wel dat het haalbaar is in de XML-schema's en dat het uitgetest wordt, o.a. in de pilot van de gemeente Den Haag.
Naar aanleiding van de opmerking van Sid dat eerder is afgesproken om geen default waarde te gebruiken bij attributen heb ik nog even onderzoek gedaan. Mijn conclusie is dat die afspraak in een geheel ander verband is gemaakt.
In de StUF Expertgroep van 20 mei vorig jaar is besloten RFC0137 af te voeren. Daar was inderdaad sprake van het default interpreteren als ‘geenWaarde’. Verschil met mijn voorstel was echter dat in RFC0137 werd voorgesteld om een element dat er niet is te interpreteren als een element waarbij het attribute ‘noValue’ de waarde ‘geenWaarde’ had. Niet verplichtte elementen zonder een waarde zouden daar dan ook weggelaten kunnen worden.
Naar mijn mening is dit een geheel andere situatie dan ik heb voorgesteld. In mijn voorstel wordt het element wel gewoon geplaatst alleen zonder attribute ‘noValue’ wat de code aanzienlijk leesbaarder maakt.
Wellicht goed om het gebruik van de default waarde i.v.m. RFC0413 alsnog te overwegen.
Ik heb het over bovenstaande nog even met Henri gehad.
In dat gesprek kwamen we er op uit dat je in het schema niet af kunt dwingen dat in geval van de waarde 'geenWaarde' geen 'noValue' attribute gebruikt moet worden. Om die reden komt het voorstel om een default waarde te gebruiken alsnog te vervallen. De discussie daarover is bij deze dan ook gesloten.
Bij de uitwerking van dit RFC zijn we tegen een aantal obstakels aangelopen. Ten eerste worden de XML-berichten onleesbaar omdat er per element twee extra regels worden gegenereerd. We hebben geëxperimenteerd met compactere elementen zoals <_:w> en <_:l> in plaats van <_:waarde> en <_:leeg>. Dat geeft ook weinig soelaas omdat xml-editors ook de compacte elementen op een nieuwe regel zetten. Ten tweede zie ik het niet gebeuren dat andere partijen binnen het stelsel of binnen de Nederlandse overheid of internationaal een dergelijke exotische constructie zullen gaan gebruiken zoals hier is voorgesteld.
Daarom stel ik voor om toch maar te gaan voor de constructie met dummies zoals voorgesteld in post #6. In dit voorstel overruled het attribute noValue de dummy waarde, bijv.:
<leeftijd StUF:noValue=”geenWaarde”>999</leeftijd>
Het gebruik van dummies komt zelden voor en op deze kunnen we de elegantie van de huidige syntax handhaven en tegelijkertijd de problemen bij codegeneratie elimineren.
In de aankomende EG hoop ik overeenstemming te krijgen over dit voorstel want dit is de basis van veel andere RFC's. Dus als je prangende bezwaren hebt tegen dit voortschrijdende inzicht, graag asap reageren op dit forum.
Tijdens de StUF Expertgroep van 19 oktober 2016 is dit RFC nogmaals besproken. De eerder gekozen oplossing heeft nl. een enorme impact, zowel m.b.t. de leesbaarheid, als de documentatie, als code generatie. Er is voorgesteld om toch maar gebruik te maken van dummy waardes als een element een datatype heeft dat geen lege waarde kan hebben. Daarbij wordt de te gebruiken waarde niet voorgeschreven.
Sid Brouwer vroeg zich af of het gebruik van deze methode t.o.v. xsi:nill nu wel zo veel winst oplevert en opperde dat we beter vast kunnen houden aan xsi:nill als dat niet zo is. Enkele leden van de StUF Expertgroep gaven echter aan dat er wel degelijk sprake is van winst m.n. op het punt van code generatie maar ook voor performance en geheugengebruik.
Het vergemakkelijken van de toetreding tot de StUF markt, waarvoor code generatie van belang is, wordt eveneens genoemd.
De StUF Expertgroep besluit om de leden de tijd te geven hierover met hun achterban te overleggen. Afgesproken is dat zij binnen 2 weken de resultaten daarvan terugkoppelen op het forum. Daarnaast wordt de gemeente Den Haag gevraagd om te bevestigen dat dit in de praktijk ook werkt.
Even terug naar de start van deze discussie. Daarin werd gesteld dat de nillable="true"-constructie (ruwweg) de volgende nadelen kent:
Wij (Centric) zien in de voorgestelde oplossing nog geen groot voordeel op die vlakken. Codegeneratie moet altijd nog rekening houden met het verwerken van de dummy-waardes (of beter het niet verwerken daarvan). Bij ontvangst van een bericht moet de waarde bewust worden genegeerd (vergt extra handmatige te schrijven code) en bij de aanmaak van het bericht moet steeds een juiste dummywaarden worden 'geïnjecteerd' waarbij gelet moet worden op domein van het type (enumeraties, beperkingen van numerieke waarden, patterns etc.).
Bovendien wordt de standaard naar onze mening niet veel minder complex bij het doorvoeren van dummywaarden waar null-waarden worden bedoeld.
Wij zouden dan ook graag (beproefd) zekerheid hebben over de mogelijke winst, voordat we een zo ingrijpende wijziging door gaan voeren in de standaard. Zoals tijdens het overleg al uitgesproken: we moeten een oplossing kunnen vinden die ook daadwerkelijk effectief is en anders kunnen we beter vasthouden aan wat we al hadden.
GouwIT is van mening dat het op deze manier verwijderen van xsi:nil geen gewenste actie is.
Net als Sid zijn wij van mening dat de verwerking van berichten niet minder complex zal worden als er maar een dummy waarde wordt gezet, software moet in plaats van het afhandelen van die node naar allerlei attributen gaan kijken om te weten wat er moet gebeuren met een ontvangen waarde maar toch ook nog de functionaliteit hebben om ervan uit te gaan dat de waarde gewoon bij de betreffende node staat.
Bij ons wordt altijd primair naar de opgestuurde waarde gekeken en pas als iets leeg is wordt er naar de reden gekeken waarom hij leeg is. Door de voorgestelde oplossing zal bij elementen die niet leeg kunnen worden gelaten (nummerieke gegevens/enumeraties etc) nooit meer de waarde kunnen worden vertrouwd, bij het ontvangen van <huisnummer>9</huisnummer> moet de software dus altijd op zoek naar een attribuut 'geenWaarde' om te zien of dit nu een leeg huisnummer is of dat het huisnummer 9 is.
Sid en Mark: vergt het implementeren van de oplossing met de choice (<waarde> of <leeg>) echt minder inspanning dan de oplossing met de dummy waarde? Over de choice hadden we per slot van rekening al overeenstemming.
Ja, als onze software <huisnummer>56</huisnummer> ontvangt zal toch weer moeten worden gecontroleerd of dit geen 'geenWaarde' huisnummer is. Bij een afgesproken waarde voor 'leeg' zal die waarde als null worden gezien, maar met de voorgestelde oplossing is er geen vaste dummy waarde en mag ik dus geen elke waarde meer op z'n blauwe ogen mogen vertrouwen.
Een nieuwe oplossing van het nillable-probleem is om het noValue attribute uit de StUF-standaard te verwijderen en de choice constructie (<waarde> of <leeg>) alleen te gebruiken bij elementen die van zichzelf geen lege waarde hebben in hun waardenbereik. Dat laatste komt sporadisch voor en bijna alleen bij datum-elementen die sowieso al een complexere definitie hebben dan reguliere elementen. We leggen het nieuwe voorstel uit aan de hand van drie situaties:
Een element heeft een waarde
Huidig: <geslachtsnaam>Janssen</geslachtsnaam>
Voorstel: idem
Huidig: <datumoverlijden>19790817</datumoverlijden>
Voorstel: <datumoverlijden>
<waarde>1979-08-17</waarde>
</datumoverlijden>
Een element heeft geen waarde
Huidig: <voorvoegsel noValue=”geenWaarde”/>
Voorstel: <voorvoegsel/>
Huidig: <datumoverlijden noValue=”geenWaarde”>
Voorstel: <datumoverlijden>
<leeg>geenWaarde</leeg>
</datumoverlijden>
Bij het element "voorvoegsel" hoeven we niet de complexe <leeg>-constructie te gebruiken omdat een voorvoegsel een lege string in zijn waardenbereik heeft.
De waarde van een element is niet nader gespecificeerd
Huidig: <geslachtsnaam noValue=”…”/>
Voorstel: element weglaten
Het attribute noValue in huidig kan hier de volgende waarden hebben:
Omdat in dit nieuwe voorstel het noValue-attribute komt te vervallen kunnen we de bovenstaande waarden niet meer gebruiken voor een verfijnde indicatie waarom een waarde niet gespecificeerd is. We leveren dus functionalitiet in, maar hoe vaak gebruiken we naast “geenWaarde” de andere noValue-waarden? Met deze drastische versimpeling lossen we wel het nillable probleem op een elegante manier op volgens het KISS-principe (Keep It Stupid Simple) ;-)
Bovenstaande oplossing voor het nillable-probleem heeft net zoals de eerdere voorstellen ook consequenties voor (bestaande) implementaties.
In een kennisgeving wordt in het laatste voorstel de weinig voorkomende overgang van een waarde naar waardeOnbekend gerepresenteerd, doordat in oud de waarde zit en in nieuw het element ontbreekt. Om dit door te voeren in de database moet dit element in het SQL-statement worden opgenomen met de waarde null. Je kunt dus niet verwerken met een update voor de elementen uit nieuw in de kennisgeving, terwijl met StUF0301 nu wel kan.
In een antwoordbericht speelt iets soortgelijks, omdat een element er om twee redenen niet in kan voorkomen:
Bij het interpreteren van het antwoord heb je dus de gestelde vraag nodig om deze twee gevallen uit elkaar te halen. Synchroon is dat relatief eenvoudig, maar asynchroon wat minder (je zult dan de vraag moeten bewaren totdat het antwoord binnenkomt).
Na een lange zoektocht zijn er drie mogelijke oplossingen voor het omzeilen van nillable=”true” overgebleven:
A) Het voorstel met de choice-constructie (<waarde> of <leeg>) toegepast op alle elementen
B) Het laatste voorstel waarin het noValue-attribute overboord wordt gegooid en de choice-constructie alleen maar wordt toegepast in het sporadische geval dat een element van zichzelf geen lege waarde heeft in het waardenbereik.
C) Het voorstel met de dummy-waarden
In de aankomende EG zal er een keuze gemaakt moeten worden anders halen we de planning niet. Mocht dat niet lukken dan zal ik genoodzaakt zijn om te escaleren naar de Regiegroep. In dat geval zal ik vragen de regiegroep een uitspraak te laten doen over de volgorde van belangrijkheid van de criteria waar een oplossing aan moet voldoen. Ik denk hierbij aan de volgende criteria:
Ad 1. Alleen als deze bovenaan wordt gezet zullen we nillable="true" uit de standaard verwijderen, anders wordt de huidige stuf0301-constructie gehandhaafd, omdat die verreweg het beste scoort op de twee andere criteria.
Ad 2. Als leesbare berichten belangrijker worden gevonden dan eenvoud van migratie, dan kiezen we voor oplossing C met dummy waarden of oplossing B waarin het attribute noValue wordt opgegeven)
Ad 3. Als migratie belangrijker is dan leesbare berichten, dan kiezen we voor de al eerder goedgekeurde oplossing A met een choice op alle elementen die de berichten bijna 3x zo lang maakt.
Ad 4. Als we (op onorthodoxe wijze) de standaard echt willen versimpelen, dan kiezen we voor oplossing B waarin het attribute noValue wordt opgeofferd.
Zonder hier nu al een uitspraak te willen doen over de te kiezen oplossing (daar kom ik in een later stadium, dan wel in de EG op terug), zou ik voor de Ad 4 nog een voorstel willen doen:
Wanneer we besluiten het noValue-attribuut af te schaffen, hebben we twee andere opties te overwegen die nog eenvoudiger zijn:
Gesteld is (in het SIG-rapport) dat vooral de combinatie van (andere) attributen samen met een nil-value problemen geeft. Met het wegvallen van de noValue, kunnen we dus ook gewoon een nil-attribuut toestaan: bij een lege waarde hoort dan immers geen ander attribuut meer (dat niet wordt gedeserialiseerd bij een xsi:nil="true"). We sluiten dan volgens mij aan bij de problemen rond codegeneratie etc., en hoeven geen bijzondere constructies te bedenken.
Hiermee zou je zelfs de nillable weg kunnen laten én hoef je geen <leeg>-constructie meer te verzinnen.
Nog even voor de duidelijkheid: ik maak hier nog geen keuze voor de oplossingsrichting, maar stel alleen dat áls we op de richting uitkomen van het verwijderen van de noValue, ik het volgens een van de twee hier genoemde methodes zou doen en niet met een <leeg>-constructie. Die voegt volgens mij namelijk niets meer toe aan de oplossing.
Op de vraag of het überhaupt wenselijk is de noValue te laten vervallen ben ik nog niet tot een conclusie gekomen...
Ad 1. Scherp Sid! Volgens mij kun je inderdaad als je het noValue attribute opoffert het xsi:nil="true" attribute weer herintroduceren zonder dat de codegeneratoren daar last van hebben. Ik zal dit nog even moeten uittesten in Visual .NET maar ik heb goede hoop dat het werkt. Dit zou een zeer waardevolle vereenvoudiging zijn van oplossing B want dan hoeven we geen choice-constructie (<waarde> of <leeg>) meer toe te passen op elementen die van zichzelf geen waarde hebben in hun waardenbereik. Dan gebruiken we gewoon weer xsi:nil="true" voor alle elementen die geen waarde hebben.
Ad 2. Deze begrijp ik nog niet helemaal. Met de herintroductie van xsi:nil="true" hoef je sowieso geen <leeg> meer te gebruiken. Zie Ad 1. En hoe maak je het onderscheid tussen geenWaarde en waardeOnbekend als je in alle gevallen het element weglaat?
Henri, punt 2 gaat iets verder dan punt 1, maar is wezenlijk niet veel anders. het enige verschil is dat je toestaat dat lege elementen weg worden gelaten. Elementen kunnen dan niet verplicht worden gemaakt, ook niet in de onderliggende regels (bijvoorbeeld bij een wijziging van leeg naar niet leeg, moet in het oude voorkomen nu het element worden opgenomen als nil of leeg -> die eis zou je dan moeten laten vervallen)
Het onderscheid tussen geenWaarde en waardeOnbekend zijn we in beide gevallen kwijt omdat we daarvoor het attribuut noValue nodig hebben. Dat onderscheid kunnen we dus in jouw oorspronkelijke voorstel (B in post #28) ook al niet meer maken. Jouw laatste vraag lijkt mij dus niet relevant, of ik begrijp jou niet goed :-)
Of het afschaffen van het noValue attribuut voldoende is vraag ik mij af, los van of dit functioneel wenselijk is. Er zijn nog tal van andere attributen die op verschillende plekken in de berichten voorkomen. Om deze discussie niet nog complexer te maken zou ik de vraag of het noValue attribuut nog wel nodig is als nieuwe discussie opvoeren als dit serieus overwogen wordt.
Maar even afgezien daarvan. In deze discussie wordt een aantal keren genoemd dat het probleem beperkt is tot een beperkt aantal elementen (datums, integers, decimals, strings met enumeraties etc.). Om hoeveel elementen gaat het precies? Dat helpt wellicht bij het beoordelen van de impact, ook voor de benodigde aanpassingen in de gegenereerde .NET code. Want er lijken ook hier best werkbare oplossingen te bestaan (zie bijv. http://stackoverflow.com/questions/38018419/deserialize-xml-element-with-xsinil-true-in-c-sharp).
Naar aanleiding van discussie https://vng-realisatie.github.io/StUF-Standaarden/discussie/gemma/stuf-bg-310/uitbreiding-waardenbereik-aanduidinginhoudingvermissing, waarbij het gebruik van enumeraties in de schema’s mogelijk wordt beperkt in de toekomst, wordt het aantal elementen waarbij het xsi:nil probleem bestaat nog kleiner.
Zoekende naar de business case voor deze aanpassingen vraag ik me af waar het zwaartepunt ligt. Het makkelijker code kunnen genereren voor m.n. nieuwe partijen die iets met StUF gaan doen versus het bestaande landschap aan applicaties die al een bestaande implementatie hebben (in de softwarecatalogus zijn het 125 pakketten) en dus naar aanleiding van de hier voorgestelde wijzigingen substantiële aanpassingen moeten doorvoeren in hun software.
@Sid,
Interessante observatie van Sid dat nillable is true geen problemen oplevert op elementen die verder geen attributes hebben. Om het weglaten van elementen in geval van een overlijdensdatum, voorvoegsels of een bsn de ambigue betekenis waardeOnbekend of geenWaarde te geven lijkt me zeer onwenselijk. Zeker bij een bsn is het lang niet altijd zo dat het weglaten dan betekent dat er geen bsn is. Ik wil daarom vasthouden aan een leeg element voor geenWaarde en het weglaten van het element bij waardeOnbekend. geenWaarde is ook semantisch gezien een geldige waarde en mag je niet op één hoop gooien met het onbekend zijn van een waarde.
Realiseer je dan wel goed wat de consequenties zijn voor het verwerken van kennisgevingen en antwoordberichten. Je hebt oud naast nieuw nodig in een kennisgeving om van de elementen die alleen in oud of nieuw voorkomen de betekenis vast te stellen in de entiteit waarin het element niet voorkomt. Richting de database is dit essentieel zowel bij het zoeken als bij het muteren.
Hetzelfde geldt voor een antwoordbericht: je hebt de scope entiteit nodig om vast te stellen dat waardeOnbekend de betekenis is van de gevraagde niet-geleverde elementen. Als je het antwoord niet door verwerkt naar een database, dan lijkt dit me geen probleem. Als je het wel doorsluist naar een database, dan zal je expliciet moeten bepalen dat de ontbrekende gevraagde elementen in de database de waardeOnbekend moeten krijgen. Ontbrekende niet-gevraagde elementen houden hun waarde in de database.
@Rolf: Ik ben het bijna helemaal eens met jouw opmerkingen in #32. Enige kanttekening die ik hier wil plaatsen is dat de meeste attributes niet worden gebruikt in combinatie met een lege waarde. Mogelijk is de inOnderzoek er een waar we naar moeten kijken (omdat daar de lege waarde als N wordt geïnterpreteerd, heeft nil hierbij veel meer betekenis), maar ik denk dat het verder wel mee zal vallen. Bij besluit voor schrappen van noValue, zouden we dat nader kunnen onderzoeken om de richting hier (keuze voor schrappen nillable="true") te bepalen.
@Maarten: Ik zie de consequenties van het schrappen van noValue nog niet zo duidelijk als jij blijkbaar doet. Een keuze op dit punt wil ik daarom (zoals ik eerder al schreef) nog niet doen. Ook valt mij op dat het verschil tussen geenWaarde, waardeOnbekend en waardeVastgesteldOnbekend semantisch in het RSGB niet beschreven is. We zouden ons dus af moeten/kunnen vragen of het vastleggen van dit onderscheid functioneel eigenlijk wel wenselijk/noodzakelijk is. Maar dit draait dan allemaal om de discussie over het wel of niet afschaffen van de noValue, waarvoor ik (net als Rolf) wel voel voor een separate discussie.
In de EG van morgen hoop ik dat we een knoop doorhakken over het nillable-probleem want liever escaleer ik niet richting Regiegroep. Een dergelijke escalatie zou sowieso vertraging betekenen. Mijn beeld van de situatie is als volgt: RFC0413 heeft tot doel codegeneratie mogelijk te maken. Deze RFC is reeds goedgekeurd. Dus men is het eens dat StUF op één of andere manier gewijzigd moet worden om codegeneratie mogelijk te maken. Echter tijdens de uitwerking van het RFC bleek dat de initiële oplossingsrichting A niet haalbaar is. Nu moeten we kiezen voor een andere oplossingsrichting die codegeneratie mogelijk maakt. Na een lange zoektocht zijn er drie mogelijkheden overgebleven:
B. Opofferen noValue-attribute en de choice-constructie alleen toepassen in het sporadische geval dat een element van zichzelf geen lege waarde heeft in het waardenbereik.
C. Het voorstel met de dummy-waarden
D. Opofferen noValue-attribute en nillable="true" toepassen op elementen die van zichzelf geen lege waarde hebben in het waardenbereik.
Ad B. Om de toepassing van de "lelijke" choice constructie zo klein mogelijk te maken kunnen we in elke enumeratie een lege string toevoegen. In oplossing D is dat niet nodig.
Henri,
Ik ben het niet helemaal met je eens. Er is een bepaalde oplossingsrichting goedgekeurd: er is niet gesteld dat kost wat kost het doel van de RFC moet worden bereikt, maar er is goedkeuring verleend aan een bepaalde oplossing voor het probleem. Nu die oplossing toch niet blijkt te werken, moet opnieuw een goede oplossing worden gevonden die weer goedkeuring krijgt van de groep. Als die niet wordt gevonden, zal de RFC alsnog kunnen worden afgekeurd.
Volgens mij maken we steeds een soort kosten/baten-afweging. Met een andere oplossing wordt die balans ook anders. Dan kan het zijn dat we de 'kosten' niet zien opwegen tegen de 'baten'. Het lijkt mij dat we in zo'n situatie zitten.
Tijdens de StUF Expertgroep van 16 november 2016 is besloten dat de gemeente Den Haag gaat checken of de opties B en D geen problemen opleveren bij code generatie. Daarnaast is afgesproken dat we gaan kijken wat de consequenties zijn van het opofferen van 'noValue' en tenslotte wordt er ook gekeken wat het verwijderen van andere attributes dan 'noValue' voor consequenties heeft. Voor deze laatste 2 punten wordt een aparte discussie geopend.
Voor het afschaffen van noValue heb ik een apart RFC gemaakt:
https://vng-realisatie.github.io/StUF-Standaarden/discussie/gemma/stuf-301/rfc-afschaffen-novalue-attribute
Graag verneem ik van de EG-leden niet later dan 30 november via het forum voor welke optie ze willen kiezen voor het oplossen van het nillable-probleem:
B. Opofferen noValue-attribute en de choice-constructie alleen toepassen in het sporadische geval dat een element van zichzelf geen lege waarde heeft in het waardenbereik.
C. Het voorstel met de dummy-waarden
D. Opofferen noValue-attribute en nillable="true" toepassen op elementen die van zichzelf geen lege waarde hebben in het waardenbereik.
Indien de meerderheid van de leden geen van deze drie opties wil of kan kiezen dan zal ik dat moeten escaleren naar de Regiegroep. Dat zal leiden tot een flinke vertraging in de oplevering van de nieuwe standaarden.
Maarten heeft in de discussie over het afschaffen van het attribute noValue nog een nieuw alternatief E ingebracht:
Definieer getallen in de schema's getallen via regular expressions die ook een lege waarde toestaan. Theoretisch lijkt het met regular expressions mogelijk te zijn om in elk element de lege waarde mogelijk te maken, terwijl de check op het zijn van een getal gewoon gehandhaafd blijft. Dit zou uitgezocht moeten worden door te kijken of alle simpleTypes in stuf0301, bg0310, zkn0310 en ztc0310 die geen string zijn, kunnen worden omgezet naar regular expressions die hetzelfde domein definiëren. Voor datums en tijdstippen hebben we dankzij GAB toch al een bijzondere constructie en daar gebruiken we het element leeg in plaats van noValue.
Officieel gezien zijn er nu vier opties waaruit gekozen kan worden:
B. Opofferen noValue-attribute en de choice-constructie alleen toepassen in het sporadische geval dat een element van zichzelf geen lege waarde heeft in het waardenbereik.
C. Het voorstel met de dummy-waarden
D. Opofferen noValue-attribute en nillable="true" toepassen op elementen die van zichzelf geen lege waarde hebben in het waardenbereik.
E. Definieer getallen in de schema's getallen via regular expressions die ook een lege waarde toestaan.
Wat mij betreft heeft Maarten in de noValue-discussie aangetoond dat opties B en D niet de juiste weg zijn. Dus voor mij blijven deze twee opties over:
C. Het voorstel met de dummy-waarden
E. Definieer getallen in de schema's getallen via regular expressions die ook een lege waarde toestaan.
Mijn voorkeur gaat uit naar optie C (dummy waarden).
Wij zouden het wel prettig vinden om in deze discussie even buiten de kaders van StUF te kijken. We lijken ons helemaal in een StUF discussie ingegraven te hebben, terwijl we aan de andere kant juist op zoek zijn naar afstemming op andere berichtenstandaarden.
Volgens mij wordt bij NEN3610 ook uitgebreid gebruik gemaakt van genereren van berichtschema's etc. Ik neem dus aan dat ze daar ook het nillable probleem opgelost hebben. Verder heeft NEN3610 ook de noValue geïmplementeerd. Ik ben wel benieuwd waarom wij niet een "NEN3610 oplossing" kunnen overnemen en deze implementeren in StUF (of melden dat NEN3610 optie C of E heeft geïmplemnteerd, dan is de keuze voor ons ook eenvoudig).
Reagerend op post #38 van Henri (verzoek om een keuze te maken) en #40:
Volgens mij is tijdens het overleg gebleken (uit een stemming tijdens de discussie) dat vier aanwezige leveranciers bij gebrek aan een goede/bevredigende oplossing de voorkeur hadden om het RFC alsnog af te wijzen. De opoffering van de noValue was een 'escape' die nog moest worden bekeken. Als deze optie komt te vervallen, dan blijft onze voorkeur om de RFC af te wijzen als er geen andere oplossingsrichtingen worden aangedragen.
Ik sluit mij bij de opmerking van Sid aan, zoals ook al aangegeven bij het vorige Expertgroep overleg.
Uit de op dit moment voorgestelde alternatieven lijkt wat ons betreft optie E de voorkeur te hebben. Daarbij teken wij aan dat het ook daarbij niet 100% vast staat dat dit gaat werken. Om die reden willen we zonder verder onderzoek op dit moment nog geen beslissing nemen. Aan KING het verzoek om alternatief E verder te onderzoeken op uitvoerbaarheid en de resultaten tijdens de eerstvolgende EG ter tafel te brengen.
Inmiddels hebben we optie E uitgezocht door voor alle simpleTypes in stuf0301, bg0310, zkn0310 en ztc0310 de simpleTypes te definiëren als een restriction op string. Als bijlage zijn de bestanden met de simpleTypes als regex bijgevoegd.
In een programma waarmee je bestanden kunt vergelijken is eenvoudig te zien wat de veranderingen zijn en om te verifiëren of de veranderingen correct zijn.
Met deze oplossing hoeven de bestaande leveranciers alleen maar nergens meer xsi:nil="true" op te nemen (een mooie uniforme oplossing) en dat degenen die gebruik maken van codegeneratie er rekening mee moeten houden dat alle velden (ook de getallen) in de gegenereerde code een string als type krijgen. Dit is een klein beetje extra werk bij het gebruik van de gegenereerde code. Het belangrijkste is dat codegeneratie nu out-of-the-box mogelijk is. De pijn wordt dus eerlijk verdeeld tussen de bestaande leveranciers en de nieuwe toetreders.
Bijlage
bg0310_simpleTypesRegEx.xsdBijgaand ook de file stuf0301_Regex.xsd
Bijlage
stuf0301_Regex.xsdIn de bijlage ook de file zkn0310_simpleTypesRegEx.xsd
Bijlage
zkn0310_simpleTypesRegEx.xsdIn de bijlage ook de file ztc0310_simpleTypesRegEx.xsd
Bijlage
ztc0310_simpleTypesRegEx.xsdBij nader inzien zijn we de union-oplossing uit post #6 (scenario 3 uit post #9) onterecht uit het oog verloren zijn. Deze lijkt beter te zijn dan de hierboven uitgewerkte oplossing E (Definieer getallen in de schema's getallen via regular expressions die ook een lege waarde toestaan). Immers unions hebben hetzelfde nadeel als oplossing E, namelijk dat getallen (integer, decimal, ...) in combinatie met unions door de meeste codegeneratoren ook omgezet zullen worden naar strings. Echter unions hebben als voordeel dat ze veel beter leesbaar en eenvoudiger te beheren zijn dan regex-expressies.
Dus bij deze herdoop ik scenario 3 uit post #9 als oplossing F:
F. Aan primitieve datatypen die van zichzelf geen lege waarde hebben zoals integer, decimal en boolean (etc.) wordt de lege string toegevoegd middels de union-contructie (zie post #6).
Ad F. Bij enumeraties wordt de lege string direct als een <xs:enumeration value=""/> element toegevoegd (zonder union).
Oplossing C (dummy waarden) heeft voor mij nog steeds de voorkeur omdat die het nilllable-probleem eenvoudig oplost en bovendien de beste code genereert (integer blijft integer en wordt niet omgezet naar een string).
Oplossing F vind ik een goede tweede optie (beter dan oplossing E).
Tijdens de StUF Expertgroep van 21 december 2016 zijn de opties E en F en hun voor- en nadelen besproken.
Ook zijn er voorstellen gedaan om bestaande voorstellen nog verder te verbeteren, zo resulteert optie E in optie G als er annotations aan toegevoegd worden waarin de regular expressions wordt toegelicht.
Er is besloten deze optie (G) uit te proberen. Andre van de Nouweland gaat dit begin januari testen.
Alle oplossingen hebben volgens de EG-leden echter nadelen en sommige leden opteren dan ook voor het handhaven
van de huidige nillable methode. Mochten de voorgestelde opties niet bruikbaar blijken te zijn dan zullen we het handhaven van de huidige methode voor moeten leggen aan de RG. Afgesproken is dat Henri hiervoor een notitie gaat opstellen.
In dat geval zullen we ook moeten aangeven hoe er in .Net met nillables omgegaan moet worden.
In de eerste post is als oplossing voor het nillable probleem het gebruik van een choice tussen een 'waarde'-element en een 'leeg'-element geopperd. Hoewel de StUF-expertgroep deze oplossing in eerste instantie heeft goedgekeurd, is deze naderhand toch verworpen omdat de xml-berichten 3x zo groot worden door het omhullende element voor de choice.
Er blijkt een variant op deze oplossing te zijn met het gebruik van de group-constructie in xml-schema. Het onderstaande schema bevat een versimpeld voorbeeld van een StUFEntiteit AEntiteit met twee elementen:
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:ns="aNamespace" targetNamespace="aNamespace" elementFormDefault="qualified" attributeFormDefault="unqualified">
<element name="aEntiteit" type="ns:AEntiteit"/>
<complexType name="AEntiteit">
<sequence>
<group ref="ns:aElement1"/>
<group ref="ns:aElement2"/>
</sequence>
</complexType>
<group name="aElement1">
<choice>
<element name="aElement1_w" type="ns:AElement"/>
<element name="aElement1_l" type="ns:NoValue"/>
</choice>
</group>
<group name="aElement2">
<choice>
<element name="aElement2_w" type="ns:AElement"/>
<element name="aElement2_l" type="ns:NoValue"/>
</choice>
</group>
<simpleType name="AElement">
<restriction base="string"/>
</simpleType>
<simpleType name="NoValue">
<restriction base="string">
<enumeration value="geenWaarde"/>
<enumeration value="waardeOnbekend"/>
</restriction>
</simpleType>
</schema>
Het volgende xml-bericht valideert tegen dit schema:
<aEntiteit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="aNamespace TestNillable.xsd" xmlns="aNamespace">
<aElement1_l>waardeOnbekend</aElement1_l>
<aElement2_w>String</aElement2_w>
</aEntiteit>
Het bericht heeft nu weer de normale lengte. We maken het onderscheid tussen een waarde en leeg voor een attribuut uit het informatiemodel door een element met '_w' als suffix, respectievelijk '_l' als suffix. Vergeleken met de StUF0301 schema's kan het gebruik van noValue nu scherper gedefinieerd worden. 'geenWaarde' kunnen we bijvoorbeeld alleen toestaan voor attributen waar 'geenWaarde' behoort tot het waardebereik van het attribuut.
Wat je met deze oplossing inlevert is het restriction mechanisme. Het is niet langer mogelijk om restrictions te maken van het complexType voor een StUF-entiteit, omdat een restriction in een group leidt tot wijziging van de group en dat wil je niet. De overgang naar de generatie van de schema's op basis van het UGM neemt dit bezwaar weg.
Pagina's