Расширение XML (B2MML standart) схемы кастомными полями

не хочу много писать, но без развёрнутого описания будет не очень понятно. И прошу тех, у кого большой опыт работы с XML схемами пробежаться по вопросу и понять суть. Основная часть работы заключается в расширении стандарта B2MML (это обычный XML, только для крупных промышленных проектов со своей архитектурой организации бизнеса) и добавлении кастомных полей. Проблемная ситуация возникла, когда нужно было добавлять UserFields в данный стандарт в несколько XML тэгов. В качестве примера рассмотрим два тэга, которые расширяют и где возникают коллизии. Схема, которую мы расширяем (имя не важно, но для людей, которые работали будет понятно) B2MML-V0600-ProductionSchedule.xsd. В данной схеме расширяем два XML элемента введите сюда описание изображения введите сюда описание изображения

Расширение данных элементов идут через другой файл B2MML-V0600-Extensions.xsd, где мы указываем свои элементы с указанием типов и пр. Ниже пример расширения, где мы добавляем кастомный элемент UserFields введите сюда описание изображения введите сюда описание изображения

После, данные XML схемы нужно конвертировать в классы C#. После конвертирования получается класс с описание свойств.

public partial class SegmentRequirementType
    {
       private SegmentRequirementTypeUserField[] userFieldsField;

        [System.Xml.Serialization.XmlArrayAttribute(Namespace = "http://www.mesa.org/xml/B2MML-V0600- 
        AllExtensions")]
        [System.Xml.Serialization.XmlArrayItemAttribute("UserField", IsNullable = false)]
        public SegmentRequirementTypeUserField[] UserFields
        {
            get
            {
                return this.userFieldsField;
            }
            set
            {
                this.userFieldsField = value;
            }
        }
    }

введите сюда описание изображения

Для другого элемента

public partial class MaterialRequirementType
    {
        private MaterialRequirementTypeUserField[] userFieldsField;
[System.Xml.Serialization.XmlArrayAttribute(Namespace = "http://www.mesa.org/xml/B2MML-V0600-AllExtensions")]
        [System.Xml.Serialization.XmlArrayItemAttribute("UserField", IsNullable = false)]
        public MaterialRequirementTypeUserField[] UserFields
        {
            get
            {
                return this.userFieldsField;
            }
            set
            {
                this.userFieldsField = value;
            }
        }
    }

введите сюда описание изображения

B2MML XML с данными имеет следующий вид (урезанный)

<?xml version=\"1.0\" encoding=\"utf-8\"?><ProcessProductionSchedule releaseID=\"0.0.2\" xmlns=\"http://www.mesa.org/xml/B2MML-V0600\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation =\"http://www.mesa.org/xml/B2MML-V0600 B2MML-V0600-ProductionSchedule.xsd\" xmlns:Extended=\"http://www.mesa.org/xml/B2MML-V0600-AllExtensions\">
<DataArea>
    <Process></Process>
    <ProductionSchedule>
        <ProductionRequest>
             <SegmentRequirement>                    
                <MaterialRequirement>
                    <Extended:UserFields>                       
                        <Extended:UserField>
                            <Extended:Name>testName</Extended:Name>
                            <Extended:Type>testType</Extended:Type>
                            <Extended:Val>testValue</Extended:Val>
                        </Extended:UserField>
                    </Extended:UserFields>                      
                </MaterialRequirement>
                <Extended:UserFields>                       
                    <Extended:UserField>
                        <Extended:Name>testName</Extended:Name>
                        <Extended:Type>testType</Extended:Type>
                        <Extended:Val>testValue</Extended:Val>
                    </Extended:UserField>
                    <Extended:UserField>
                        <Extended:Name>testName</Extended:Name>
                        <Extended:Type>testType</Extended:Type>
                        <Extended:Val>testValue</Extended:Val>
                    </Extended:UserField>
                </Extended:UserFields>  
            </SegmentRequirement>                
        </ProductionRequest>
    </ProductionSchedule>
</DataArea>
    </ProcessProductionSchedule>"

Когда я в C# пытаюсь получить данный документ и произвести его десериализацию введите сюда описание изображения , то я получаю ошибки:

  • error CS0030: Преобразование типа "Deserialize.Scheduler.SegmentRequirementTypeUserField[]" в "Deserialize.Scheduler.MaterialRequirementTypeUserField[]" невозможно
  • error CS0029: Неявное преобразование типа "Deserialize.Scheduler.MaterialRequirementTypeUserField[]" в "Deserialize.Scheduler.SegmentRequirementTypeUserField[]" невозможно

Складывается впечатление, что независимо от типа хранимых переменных внутри массива userFieldsField, а это MaterialRequirementTypeUserField и SegmentRequirementTypeUserField, система пытается сохраниться массив объектов в одну область памяти, так как два данных типа, указынных выше имеют одни и те же свойства (но это мои предположения).

Я нашёл обходное решение данной проблемы, которое можно использовать как крайний вариант. Если исходную схему изменить к такому виду: введите сюда описание изображения введите сюда описание изображения

Указав для корневых элементов UserFields уникальные имена и создав новый класс с уникльными именами и уникальными именами в XML data документе, то десериализация проходит без ошибок.

Огромное спасибо, если дочитали до этой строчки!!!


Ответы (1 шт):

Автор решения: Denis Danilov

Получилось пофиксить данный кейс введением общего типа для данных массивов, поскольку набор свойств объектов массива одинаков.

[![введите сюда описание изображения][1]][1]

Не знаю почему, но если имеется несколько массивов, элементы которых имеют разные типы, но эти типы, классы с одинаковым набором однотипных полей, то возможно происходит какая-то внутренняя оптимизация. Вопрос закрыт. [1]: https://i.stack.imgur.com/T6jvA.png

→ Ссылка