W deserializacji XML .NET, w jaki sposób mogę pozwolić na polimorficzne użycie typów tablicowych?
Przykładowy schemat:
<code><complexType name="Dog">...</complexType> <complexType name="Cat">...</complexType> <complexType name="ArrayOfDog"> <sequence> <element name="Dog" type="tns:Dog minOccurs="0" maxOccurs="unbounded" /> </sequence> </complexType> <complexType name="Foo"> <sequence> <element name="Bar" type="string"/> <element name="Baz" type="anyType"/> </sequence> </complexType> </code>
Uruchomienie tego za pomocą narzędzia wsdl.exe .NET generuje kod podobny do następującego:
<code>[System.Xml.Serialization.XmlIncludeAttribute(typeof(Dog[]))] public partial class Dog { ... } public partial class Cat { ... } public partial class Foo { private string barField; private object bazField; } </code>
Wygląda na to, że wsdl.exe próbuje być „inteligentny” i zdaje sobie sprawę, że mój ArrayOfDog jest tak naprawdę tylko typem opakowania, który może być zakodowany jako tablica C #. Działa to dobrze, gdy ArrayOfDog jest jawnie przywoływany w innym typie danych. Jednakże, gdy ArrayOfDog jest używany polimorficznie (np. Jako podstawienie dla xsd: anyType), to się psuje. Wygląda na to, że się załamuje, ponieważ środowisko wykonawcze .NET nic nie wie o typie złożonym o nazwie „ArrayOfDog” - zasadniczo odrzuciło te informacje na korzyść używania rodzimych tablic C #.
Przykładowy dokument XML 1:
<code><Foo> <Bar>Hello</Bar> <Baz xsi:type="Cat"> ... </Baz> </Foo> </code>
Przykładowy dokument XML 2:
<code><Foo> <Bar>Hello</Bar> <Baz xsi:type="ArrayOfDog"> <Dog>...</Dog> <Dog>...</Dog> </Baz> </Foo> </code>
Dokument # 1 jest prawidłowo deserializowany przez środowisko wykonawcze. Dostaję obiekt typu Foo z poprawnie deserializowanymi polami dla Bar i Baz.
Dokument # 2 jest deserializowanynieprawidłowo przez środowisko wykonawcze. Dostaję obiekt typu Foo z poprawnie deserializowanym polem dla Bar, ale dla pola Baz otrzymuję System.XML.XMLNode []. Domyślam się, że środowisko wykonawcze nic nie wie o żadnym powiązaniu typu dla encji o nazwie „ArrayOfDog”. Można by pomyśleć, że dyrektywa XmlInclude „XmlIncludeAttribute (typeof (Dog []))” „poradzi sobie z tym, ale nie działa.
Czy ktoś to spotkał?
Czy jest tu eleganckie rozwiązanie? Rozwiązaniem, które zamierzam użyć, jest zawinięcie mojego typu „ArrayOf” w inny typ i uwzględnienie go w podstawieniu dla xsd: anyType.