Closed florin141 closed 4 years ago
Which arguments do you use when generating code? Can you post the XML you're trying to deserialize?
I am using this test to generate the classes. As for the XML that I'm trying to deserialize, I'm getting the same exception for all of these XML files.
You can clone this forked aixm-bindings-sharp repo and see for yourself. The 'XmlSchemaClassGenerator' branch has the classes generated by the above test and all the resulting namespace errors fixed (manually).
First off, I think the namespace errors occur because there is a C# namespace that has the same segment name "aixm" at different levels in the namespace hierarchy, i.e. there is both aixm.v5_1_1
and aero.aixm.schema._5_1_1.extensions.eur.adr
. If you use e.g. aero.aixm.v5_1_1
it works.
The real problem, though, is related to #36, in particular limitation 1 mentioned by @John-Welch here: https://github.com/mganss/XmlSchemaClassGenerator/issues/36#issuecomment-426937573
I no longer have the namespace errors, thanks to your observation.
With respect to limitation 1 mentioned by @John-Welch, can you expand a bit on that? Like what needs to be implemented so that I can deserialize these files.
The problem is with a more complex hierarchy of substitutions. The aixm schema is the most complex in this regard I have encountered thus far (other ones in our test suite that use substitution groups are is24immotransfer and bpmn). Expanding on the example in #36, if you have this:
<element name="vehicleElement" type="test:vehicle" abstract="true" />
<element name="vehicleElement2" type="test:vehicle" abstract="true" />
<element name="car2" type="test:car" substitutionGroup="test:vehicleElement"/>
<element name="bus2" type="test:bus" substitutionGroup="test:vehicleElement2"/>
<element name="fleet">
<complexType>
<sequence>
<element maxOccurs="unbounded" ref="test:vehicleElement"/>
<element maxOccurs="unbounded" ref="test:vehicleElement2"/>
</sequence>
</complexType>
</element>
The current code in master puts an XmlElementAttribute
for both car2
and bus2
on both vehicleElement
and vehicleElement2
, although car2
cannot be substituted for vehicleElement2
(likewise for bus2
and vehicleElement
). This results in the exception you're getting:
The XML element '...' from namespace '...' is already present in the current scope.
Initially I thought that we could solve this by more correctly mapping the substituted elements but this only uncovers another problem: Some substituted elements have the same type so you'll end up with something like this (I made this up):
[XmlElement("car1", Type=typeof(Car), Namespace="...")]
[XmlElement("car2", Type=typeof(Car), Namespace="...")]
public Vehicle Car { get; set; }
This results in a different runtime exception ("please use XmlChoiceIdentifier" or similar) because the serializer wouldn't know which element to serialize into if it encounters an object of type Car
.
So I came up with another possible solution: Every substituted element gets its own property. I have an implementation in the substitution
branch that passes the current test suite and at first glance seems to work with aixm. I still had to massage the generated code a little:
CollectionSettersMode = CollectionSettersMode.Public
otherwise you'll get a runtime exception (no idea why)AbstractGeometry.AxisLabels
to AxisLabels2
(name clash between attribute and element)AbstractGMLType.Name
to Name2
(name clash across inheritance levels I think)Also, the example XML has wrong namespaces: replace "5.1" with "5.1.1".
One thing I've noticed perusing the deserialized AirportHeliportType
is that the gml:id
is null. No idea what's happening there.
Please check it out and report your findings.
I think your implementation from substitution branch is working.
The only exception I noticed is the Id (gml:id) that is left null when deserializing. Also, I noticed that if I remove the namespace prefix from the XML file, the value is picked up correctly.
In rest, everything seems perfect. Great job!!!
I've added code to avoid the name clashes and make the gml:id
work. The latter issue was because global attributes weren't handled properly.
I have also expanded the unit test to check de/serialization of the Aixm sample files but I'm getting this now when creating an XmlSerializer
object:
System.PlatformNotSupportedException: 'Compiling JScript/CSharp scripts is not supported'
This is on .NET Core. My console app was .NET Framework. The error does occur there, too, if I target .NET Core. Do you see this, too?
I'm only using .NET Core to generate the code, however the same error occurs when I try to create an XmlSerializer on .NET Core 3.1 and just for curiosity, I tried to create that object on .NET Core 2.2 and the same error appears (on .NET Core 1.1, I get like -2147483648 errors lol)
I'm using the generated code on a .NET Framework 4.6.2, so, I have no problem serializing/deserializing and now the gml:id is showing up.
Seems like that setting the Form property is key, as I was just testing some code from another schema that is build on top of AIXM 5.1.1 XML Schema. That schema has the form for attributes and for elements set to default (that is the attribute attributeFormDefault and elementFormDefault is not even added in the schema) resulting in all properties to be left null when I try to deserialize. I'll post the schema and a couple of examples today and you can get a better picture then.
One more thing I noticed is that a 'Name' property of a certain type is defined in an abstract class and that most derived classes also have 'Name' property but of a different type. I think that to avoid those conflicts, the name of the property in the derived class is now something like 'Name1'. Is that something you intended to do?
Seems like that setting the Form property is key, as I was just testing some code from another schema that is build on top of AIXM 5.1.1 XML Schema. That schema has the form for attributes and for elements set to default (that is the attribute attributeFormDefault and elementFormDefault is not even added in the schema) resulting in all properties to be left null when I try to deserialize. I'll post the schema and a couple of examples today and you can get a better picture then.
OK thanks. Feel free to open a separate issue for this.
One more thing I noticed is that a 'Name' property of a certain type is defined in an abstract class and that most derived classes also have 'Name' property but of a different type. I think that to avoid those conflicts, the name of the property in the derived class is now something like 'Name1'. Is that something you intended to do?
Yes, exactly.
I have the following AIXM 5.1 XML Schema and when I try to deserialize some XML I get this exception. Any idea on how to fix that?
I'm trying to replace the classed generated with the xsd.exe tool for this github repo aixm-bindings-sharp.