Проблема с десериализацией XML в сгенерированные классы XSD

У меня есть довольно подробный xml-файл. Ниже представлены узлы верхнего уровня (я включил эллипс, поскольку все узлы нижнего уровня правильно сформированы и правильно заполнены данными):

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <Models>...</Models>
    <Data>...</Data>
</config>

Я создал файл xsd с помощью командной строки Visual Studio 2008:

xsd sample.xml

Это создает файл xsd просто отлично. Затем я автоматически генерирую классы из xsd с помощью команды:

xsd sample.xsd /classes

Для десериализации файла xml в объект класса я использую функцию чтения во вспомогательном классе:

public class XmlSerializerHelper<T>
{
    public Type _type;

    public XmlSerializerHelper()
    {
        _type = typeof(T);
    }

    public void Save(string path, object obj)
    {
        using (TextWriter textWriter = new StreamWriter(path))
        {
            XmlSerializer serializer = new XmlSerializer(_type);
            serializer.Serialize(textWriter, obj);
        }
    }

    public T Read(string path)
    {
        T result;
        using (TextReader textReader = new StreamReader(path))
        {
            XmlSerializer deserializer = new XmlSerializer(_type);
            result = (T)deserializer.Deserialize(textReader);
        }
        return result;
    }
}

При попытке десериализации с помощью:

var helper = new XmlSerializerHelper<configModels>();
var obj = new configModels();
obj = helper.Read(filepath);

Я получаю сообщение об ошибке, которое, как я понял, связано с тем, что десериализатор ищет узел «Модели», но соответствующее имя класса было сгенерировано как комбинация корневого узла и узла «Модель» (configModels). Почему имена классов генерируются именно так?

Я попытался десериализовать с верхнего узла, используя:

var helper = new XmlSerializerHelper<config>();
var obj = new config();
obj = helper.Read(filepath);

К сожалению, это приводит к множеству ошибок, подобных следующим:

System.InvalidOperationException was unhandled by user code
Message="Unable to generate a temporary class (result=1).
error CS0030: Cannot convert type 'Application.Lease[]' to 'Application.Lease'
error CS0030: Cannot convert type 'Application.CashFlow[]' to 'Application.CashFlow'
...ect.

Может ли кто-нибудь направить меня к тому, что я могу делать неправильно с моей автоматической генерацией xsd?


person gun_shy    schedule 14.09.2009    source источник
comment
Ни один из автоматизированных инструментов не выдаст правильный код. Я вручную написал объектный код для десериализации xml.   -  person gun_shy    schedule 22.10.2009
comment
Не могли бы вы отметить ответ marc_s как правильный, поскольку вы сказали, что он решил вашу проблему?   -  person Win    schedule 29.08.2012


Ответы (4)


XSD.EXE — хорошее начало, но далеко не идеальное. Кроме того, на основе предоставленного вами XML XSD.EXE не всегда может точно решить, является ли что-то одним экземпляром объекта или открытым массивом объектов.

Похоже, это относится к вашим двум элементам - Application.Lease и Application.CashFlow. Как они определены в сгенерированном файле XSD? Это имеет для вас смысл? Вполне возможно, вам придется добавить небольшие подсказки, такие как:

<xs:element name="Lease" minOccurs="0" maxOccurs="1" />

для необязательного свойства это ноль или только одно вхождение. Инструменту xsd.exe очень сложно разобраться в подобных вещах, основываясь только на одном файле образца XML.

Марк

person marc_s    schedule 14.09.2009
comment
Марк, вы правы в деньгах, ваше решение решило проблему для меня. Вручную обновив значения minOccurs и maxOccurs в элементах-нарушителях, а затем запустив XSD2CODE для создания моих классов, я решил эту проблему. - person ProNotion; 01.09.2011

Перейдите к сгенерированному классу и измените все с [][] ---> []

person Ojas Maru    schedule 13.01.2012
comment
Хотя это решит проблему, ответ marc_s объясняет, почему это необходимо и как этого избежать. - person MyItchyChin; 09.07.2014

Есть проблема с xsd.exe и списками. Вы должны войти в сгенерированный класс и вручную отредактировать файл до нужного типа. Я перешел на использование Xsd2Code. Пока такой проблемы вроде нет.

person John Kraft    schedule 14.09.2009
comment
Я только что попробовал Xsd2Code, и он тоже дает мне те же ошибки преобразования со списками. - person gun_shy; 14.09.2009
comment
Не следует ли использовать xsd.exe для автоматического создания файла xsd? - person gun_shy; 14.09.2009
comment
Вы можете использовать его просто отлично. Вам просто нужно зайти в сгенерированный класс и отредактировать его вручную. Однако, если бы у Xsd2Code тоже были проблемы, мне пришлось бы согласиться с @marc_s; вероятно, проблема связана с вашей XML-схемой. - person John Kraft; 14.09.2009
comment
Только что попробовал Xsd2Code после множества проблем с другим инструментом, и он отлично сработал! Неправильно напрямую, но ошибки были достаточно описательными, чтобы решить все в течение 5-10 минут! - person Gabriël; 10.11.2009

Другая проблема, которая может вызвать эту проблему, заключается в том, что содержимое файла xml между тегами (имеется в виду содержимое) все еще закодировано, хотя этого не должно быть. Например, теги <br> в моем контенте по-прежнему были <br> вместо &lt;br /&gt;. Генератор xsd превратил их в элементы схемы, а затем ошибочно пометил их как неограниченные, поскольку было найдено более одного. Их расшифровка устранила проблему и правильно сгенерировала классы.

person DFBerry    schedule 31.05.2012