Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

An element that wraps a sequence is skipped on generation #225

Closed
Ekkeir opened this issue Sep 22, 2020 · 2 comments
Closed

An element that wraps a sequence is skipped on generation #225

Ekkeir opened this issue Sep 22, 2020 · 2 comments

Comments

@Ekkeir
Copy link

Ekkeir commented Sep 22, 2020

I've encountered a behaviour when some types are "stepped over" on class generation. Ot at least it seems so.
I apologize in advance for a bit of a messy test case. I got rid of everything I felt could be safely removed.

Consider the following scheme (let's call it Application.xsd). Essentially - we have an Application class with 3 complex fields.

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
	 xmlns="test_generation_namespace/application.xsd"
	 xmlns:ct="test_generation_namespace/commontypes.xsd"
	 xmlns:cm="test_generation_namespace/common.xsd"
	 xmlns:tsk="test_generation_namespace/task.xsd"
	 targetNamespace="test_generation_namespace/application.xsd"
	 version="1.1"
	 elementFormDefault="qualified"
	 attributeFormDefault="unqualified">
	<xs:import namespace="test_generation_namespace/commontypes.xsd" schemaLocation="TheCommonTypes.xsd"/>
	<xs:import namespace="test_generation_namespace/task.xsd" schemaLocation="Task.xsd"/>
	<xs:import namespace="test_generation_namespace/common.xsd" schemaLocation="Common.xsd"/>
	<xs:complexType name="T_Application">
		<xs:sequence>
			<xs:element name="PhaseList" type="tsk:T_PhaseList" minOccurs="0"/>
			<xs:element name="StageList" type="tsk:T_StageList" minOccurs="0"/>
			<xs:element name="OptionList" type="cm:T_OptionList" minOccurs="0"/>
		</xs:sequence>
	</xs:complexType>
	<xs:element name="Application" type="T_Application"/>
</xs:schema>

There're the linked schemes:
TheCommonTypes.xsd

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
	 xmlns="test_generation_namespace/commontypes.xsd"
	 targetNamespace="test_generation_namespace/commontypes.xsd"
	 version="1.1"
	 elementFormDefault="qualified"
	 attributeFormDefault="unqualified">
	<xs:complexType name="T_NameValue">
		<xs:sequence>
			<xs:element name="Name" type="xs:string"/>
			<xs:element name="Value" type="xs:string" minOccurs="0"/>
		</xs:sequence>
	</xs:complexType>
</xs:schema>

Task.xsd

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
	 xmlns="test_generation_namespace/task.xsd"
	 xmlns:ct="test_generation_namespace/commontypes.xsd"
	 targetNamespace="test_generation_namespace/task.xsd"
	 version="1.1"
	 elementFormDefault="qualified"
	 attributeFormDefault="unqualified">
	<xs:import namespace="test_generation_namespace/commontypes.xsd" schemaLocation="TheCommonTypes.xsd"/>
	<xs:import namespace="test_generation_namespace/common.xsd" schemaLocation="Common.xsd"/>
	<xs:complexType name="T_Stage">
		<xs:sequence>
			<xs:element name="Name" type="xs:string" minOccurs="0"/>
		</xs:sequence>
	</xs:complexType>
	<xs:complexType name="T_StageList">
		<xs:sequence>
			<xs:element name="Stage" type="T_Stage" minOccurs="0" maxOccurs="unbounded"/>
		</xs:sequence>
	</xs:complexType>
	<xs:complexType name="T_PhaseInfo">
		<xs:sequence>
			<xs:element name="Code" type="xs:string" minOccurs="0"/>
			<xs:element name="StageList" type="T_StageList"/>
		</xs:sequence>
		<xs:attribute name="active" type="xs:boolean"/>
	</xs:complexType>
	<xs:element name="PhaseInfo" type="T_PhaseInfo"/>
	<xs:complexType name="T_PhaseList">
		<xs:sequence>
			<xs:element name="Phase" type="T_PhaseInfo" minOccurs="0" maxOccurs="unbounded"/>
		</xs:sequence>
	</xs:complexType>
</xs:schema>

Common.xsd

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
	 xmlns="test_generation_namespace/common.xsd"
	 xmlns:ct="test_generation_namespace/commontypes.xsd"
	 targetNamespace="test_generation_namespace/common.xsd"
	 version="1.1"
	 elementFormDefault="qualified"
	 attributeFormDefault="unqualified">
	<xs:import namespace="test_generation_namespace/commontypes.xsd" schemaLocation="TheCommonTypes.xsd"/>
	<xs:complexType name="T_NameValue">
		<xs:sequence>
			<xs:element name="Name" type="xs:string"/>
			<xs:element name="Value" type="xs:string" minOccurs="0"/>
		</xs:sequence>
	</xs:complexType>
	<xs:complexType name="T_OptionList">
		<xs:sequence>
			<xs:element name="Option" type="T_NameValue" minOccurs="0" maxOccurs="unbounded"/>
		</xs:sequence>
	</xs:complexType>
</xs:schema>

When generated, T_Application class has the following properties:
PhaseList - is an array of T_PhaseInfo, instead of an instance of T_PhaseList that wraps it
StageList - an array of T_Stage, instead of T_StageList
OptionList - an array of T_NameValue instead of T_OptionList.

Or, as an extract:

public partial class T_Application
{
    private GenerationTestCase.Test_Generation_Namespace.T_PhaseInfo[] _phaseList;        
    public GenerationTestCase.Test_Generation_Namespace.T_PhaseInfo[] PhaseList {...}

    private GenerationTestCase.Test_Generation_Namespace.T_Stage[] _stageList;
    public GenerationTestCase.Test_Generation_Namespace.T_Stage[] StageList {...}

    private GenerationTestCase.Test_Generation_Namespace.T_NameValue[] _optionList;
    public GenerationTestCase.Test_Generation_Namespace.T_NameValue[] OptionList {...}
}

This seems to be an unexpected outcome.
Am I doing anything wrong there?
Thanks in advance.

Code used to generate the classes:

var generator = new Generator
            {
                OutputFolder = "GenerationResult",
                GenerateNullables = false,
                CollectionType = typeof(Array),
                CollectionSettersMode = CollectionSettersMode.Public,
                GenerateComplexTypesForCollections = true,
                NamespacePrefix = "GenerationTestCase",
                GenerateDescriptionAttribute = true,
                GenerateDebuggerStepThroughAttribute = true,
                DisableComments = false,
                SeparateClasses = true,
            };

            generator.Generate(new[]
            {
                @"..\..\..\XsdGenerationTest\Application.xsd",
            });
@mganss
Copy link
Owner

mganss commented Sep 23, 2020

This is a feature (enabled through XmlArrayItemAttribute). It allows you to skip the redundant intermediate class (which would have just a single collection property but not have collection semantics). In this sense, the C# collection class (e.g. T_PhaseInfo[]) represents the intermediate class of the XML Schema (e.g. T_PhaseList). Is there something you feel is missing due to this approach?

@Ekkeir
Copy link
Author

Ekkeir commented Sep 23, 2020

It seems that the root issue has been fixed between versions 2.0.434.0 and 2.0.444.0 of the library.
Serialized xml differed in structure for the older version so I had to change the classes manually, but classes produced by the newest version serialize correctly.

Sorry for taking your time and thank you for your help. Your library is an immense help.

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

No branches or pull requests

2 participants