Zine.net online

Witaj na Zine.net online Zaloguj się | Rejestracja | Pomoc
w Szukaj

dev2dev

XSD.EXE Utility – Uwaga na elementy wyliczane (i nie tylko).

XSD.EXE jest bardzo wygodnym narzędziem, przekształcającym definicję dokumentu XML zawartą w pliku XSD w postać klasy. Ale jest pewien przypadek, który powinien zwrócić naszą szczególną uwagę.

Rzecz dotyczy elementów, które w definicji XSD mają określenie wyliczanych zawartości poprzez specyfikację listy dopuszczalnych wartości. Jest to istotne gdy budujemy automaty mapujące z dokumentów XML do innych obiektów.

Rozparzmy dwa przypadki.

I. Elementy listy są napisami. Czyli na przykład tak:

image

Oto jak wygląda stosowny typ wygenerowany na podstawie tej definicji:

image

Czyli wygląda jak najbardziej tak jakbyśmy tego oczekiwali.

II. Elementy listy są liczbami. Czyli na przykład tak:

image

A tak wygląda odpowiadający temu kod wygenerowany przez XSD utility:

image

Widać tutaj, że XSD.EXE utility nie może z oczywistych względów (identyfikator nie może zaczynać sie od cyfry) wygenerować identycznych elementów w typie wyliczanym klasy takich jakie są zawarte w definicji XSD. Ale na szczęście widać, że każdy elementów typu wyliczanego ma ustawioną wartość atrybutu XmlEnumAttribute na wartość dokładnie odpowiadającą tej, która była zawarta w dokumencie XSD. Przy zastosowaniu refleksji można bardzo prosto sobie poradzić z tą niedogodnością.

Problem z elementami wyliczanymi będącymi liczbami został elegancko rozwiązany przez twórcę tego utility ale kompletnie nie rozumiem, dlaczego w przypadku elementów dokumentu XML, które mają definicję

minOccur=”0” maxOccur=”1”

nie zostały zastosowane typy null’owalne a miast tego wprowadzone zostało dodatkowe pole logiczne o takiej samej nazwie jak element lecz z dodaniem “Specified”, które ma wartość true gdy występuje w aktualnie deserializwanym dokumencie XML i false gdy nie występuje. W związku z tym trzeba budować mało eleganckie rozwiązania ponieważ takie pole w zdeserializowanej klasie, dla elementu którego brak w aktualnym dokumencie XML ma wartość domyślną zadeklarowanego typu, czyli przy następującej definicji:

private int IDField;

private bool IDFieldSpecified;

jeżeli w aktualnym dokumencie zabraknie elementu ID, to pole IDField będzie miało wartość 0, co oczywiście nie odpowiada stanowi faktycznemu. Dla tego typu przypadków trzeba sprawdzać czy klasa nie posiada aby “stowarzyszonego” pola o nazwie poszerzonej o słowo “Specified”. I dopiero gdy ma ono wartość true to możemy być pewni, że w dokumencie XML element ID ma wartość 0. O ileż prościej byłoby gdyby zastąpić powyższą definicję taką definicją:

private Nullable<int> IDField;

I wtedy 0 byłoby oczywistym zerem, a brak elementu lub atrybutu generowałby po “bożemu” null. O ileż byłoby prościej.

Opublikowane 17 maja 2009 22:30 przez marekpow
Filed under: , , ,

Komentarze:

 

Wojciech Gebczyk said:

moze dlatego ze takie zachowanie ylo przed nulowalnymi jeszcze (o ile pamietam) - a z tego juz wynika odpowiedz - MS przeciez boi sie zmian powodujacych zlamanie kompatybilnosci...

maja 18, 2009 14:22
 

marekpow said:

Też mi taka myśl błysnęła. Ale zawsze wtedy można zrobić XSD2.EXE...

maja 18, 2009 16:42
 

dotnetomaniak.pl said:

Dziękujemy za publikację - Trackback z dotnetomaniak.pl

maja 18, 2009 17:26
 

awake said:

Przydałoby się również wsparcie dla typów generycznych, a dokładnie np. dla List. Strasznie wku...wia zabawa z tablicami.

Marek... bierz źródła i zabieraj się do roboty :)

maja 20, 2009 08:39
 

Wojciech Gebczyk said:

poniewaz "wk***anie" i "ladnosc" kodu generowanego zalezy od gustow a z tymi nie dyskutuje sie zazwyczaj, wiec robienie nowego xsd srednio ma sens. Poprostu dla generowania z xsd kodu C# jaki sie chce mozna zaprzac do roboty t4 - raz piszemy skrypt i reuzywamy...

maja 20, 2009 09:51
Komentarze anonimowe wyłączone
W oparciu o Community Server (Personal Edition), Telligent Systems