Расширение DataSet
От: Аноним  
Дата: 23.05.08 07:25
Оценка:
Добрый день, уважаемые!
У меня есть пара небольших проблем:
1. Есть наследник типизированного DataSet, в который я добавил public-поле — класс. При этом XmlSerializer на него никак не отреагировал, то есть продолжил сериализовать как и базовый класс. Я переописал IXmlSerializable, но обнаружилась ситуация, когда вместо развернутого xml из датасета сериализуется какой-то куцый кусок (в котором, в принципе, данные все есть, но нет дополнительной информации наподобие diffgr:diffgram). Хотелось бы, чтобы мой классик как-нибудь поорганичнее вписался в имеемую структуру, куда копать?
2. Для этого самого классика я также переописал IXmlSerializable. Теперь наблюдаю такое поведение: когда класс сериализуется сам по себе, то xml обрамляется корневым тегом из имени класса. Если же я сериализую его как поле другого класса — корневой элемент не пишется. Поэтому приходится писать его руками в WriteXml и при сериализации самого класса получается ненужное дублирование. Подскажите, что можно предпринять?

[Serializable]
[XmlSchemaProvider("GetDocumentBaseSchema")]
public abstract class DocumentBase : IXmlSerializable
{
    public virtual void ReadXml(System.Xml.XmlReader reader)
    {
        reader.ReadStartElement("version", XmlService.mseNamespace);

        _ID = Convert.ToInt32(reader.ReadElementString("ID"));

        reader.ReadEndElement();
    }
    public virtual void WriteXml(System.Xml.XmlWriter writer)
    {
        writer.WriteStartElement("version", XmlService.mseNamespace);

        writer.WriteElementString("ID", _ID.ToString());

        writer.WriteEndElement();
    }
    public static XmlQualifiedName GetDocumentBaseSchema(XmlSchemaSet xs)
    {
        xs.Add(DocumentBaseSchema);

        return new XmlQualifiedName("version", XmlService.mseNamespace);
    }
    public static XmlSchema DocumentBaseSchema
    {
        get
        {
            XmlSchema result = new XmlSchema();

            result.ElementFormDefault = XmlSchemaForm.Qualified;

            result.Namespaces.Add("xs", XmlService.xsNamespace);
            result.TargetNamespace = XmlService.mseNamespace;

            XmlSchemaSequence ss = new XmlSchemaSequence();

            XmlSchemaElement xe = new XmlSchemaElement();
            xe.Name = "ID";
            xe.SchemaTypeName = new XmlQualifiedName("int", XmlService.xsNamespace);
            ss.Items.Add(xe);

            XmlSchemaComplexType sc = new XmlSchemaComplexType();
            sc.Name = "version";
            sc.Particle = ss;

            result.Items.Add(sc);

            return result;
        }
    }
}

[Serializable]
[XmlSchemaProvider("GetProjectSchema")]
public class Project : DocumentBase, IXmlSerializable
{
    public override void ReadXml(System.Xml.XmlReader reader)
    {
        reader.ReadStartElement("project", XmlService.mseNamespace);

        base.ReadXml(reader);

        _path = reader.ReadElementString("path");

        reader.ReadEndElement();
    }
    public override void WriteXml(System.Xml.XmlWriter writer)
    {
        writer.WriteStartElement("project", XmlService.mseNamespace);

        base.WriteXml(writer);

        writer.WriteElementString("path", _path);

        writer.WriteEndElement();
    }
    public static XmlQualifiedName GetProjectSchema(XmlSchemaSet xs)
    {
        xs.Add(ProjectSchema);

        return new XmlQualifiedName("project", XmlService.mseNamespace);
    }
    public static XmlSchema ProjectSchema
    {
        get
        {
            XmlSchema result = new XmlSchema();

            result.ElementFormDefault = XmlSchemaForm.Qualified;

            result.Namespaces.Add("xs", XmlService.xsNamespace);
            result.Namespaces.Add("mse", XmlService.mseNamespace);
            result.TargetNamespace = XmlService.mseNamespace;

            XmlSchemaInclude xi = new XmlSchemaInclude();
            xi.Schema = DocumentBaseSchema;
            xi.SchemaLocation = "DocumentBase.xsd";
            result.Includes.Add(xi);

            XmlSchemaSequence ss = new XmlSchemaSequence();

            XmlSchemaElement xe = new XmlSchemaElement();
            xe.Name = "version";
            xe.SchemaTypeName = new XmlQualifiedName("version", XmlService.mseNamespace);
            ss.Items.Add(xe);

            xe = new XmlSchemaElement();
            xe.Name = "path";
            xe.SchemaTypeName = new XmlQualifiedName("string", XmlService.xsNamespace);
            ss.Items.Add(xe);

            XmlSchemaComplexType sc = new XmlSchemaComplexType();
            sc.Name = "project";
            sc.Particle = ss;

            result.Items.Add(sc);

            return result;
        }
    }
}
[Serializable]
[XmlSchemaProvider("GetProjectDataSetSchema")]
public class ProjectDataSet : ProjectDataSetBase, IXmlSerializable
{
    void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
    {
        reader.ReadStartElement("ProjectDataSet", XmlService.mseNamespace);

        base.ReadXml(reader);

        _project.ReadXml(reader);

        reader.ReadEndElement();
    }
    void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
    {
        base.WriteXml(writer);

        _project.WriteXml(writer);
    }
    public static XmlQualifiedName GetProjectDataSetSchema(XmlSchemaSet xs)
    {
        xs.Add(ProjectDataSetSchema);

        return new XmlQualifiedName("ProjectDataSet", XmlService.mseNamespace);
    }
    public static XmlSchema ProjectDataSetSchema
    {
        get
        {
            XmlSchema result = new XmlSchema();

            result.ElementFormDefault = XmlSchemaForm.Qualified;

            XmlSchema schema = (new ProjectDataSet()).GetSchemaSerializable();

            XmlSchemaSequence ss = new XmlSchemaSequence();

            foreach (XmlSchemaObject item in schema.Items)
                ss.Items.Add(item);

            result.Namespaces = schema.Namespaces;
            result.Namespaces.Add("mse", XmlService.mseNamespace);
            result.TargetNamespace = XmlService.mseNamespace;

            XmlSchemaInclude xi = new XmlSchemaInclude();
            xi.Schema = Project.ProjectSchema;
            xi.SchemaLocation = "Project.xsd";
            result.Includes.Add(xi);

            XmlSchemaElement xe = new XmlSchemaElement();
            xe.Name = "project";
            xe.SchemaTypeName = new XmlQualifiedName("project", XmlService.mseNamespace);
            ss.Items.Add(xe);

            XmlSchemaComplexType sc = new XmlSchemaComplexType();
            sc.Name = "ProjectDataSet";
            sc.Particle = ss;

            result.Items.Add(sc);

            return result;
        }
    }
}
Re: Расширение DataSet
От: Аноним  
Дата: 26.05.08 11:30
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Добрый день, уважаемые!

А>У меня есть пара небольших проблем:

Никто ничего похожего не делал или я объяснил криво?
Re[2]: Расширение DataSet
От: Mr. Cornel  
Дата: 23.01.09 18:21
Оценка:
А>Никто ничего похожего не делал или я объяснил криво?
Приветствую. Действительно, похоже мало кто имел с этими вопросами дело. В Вашем исходном сообщении меня заинтересовал факт "дублирования". Насколько я могу судить, мы своими WriteXml/ReadXml основательно вмешиваемся в обычный процесс сериализации и поэтому необходимы более глубокие знания для осознания происходящего.

К сожалению, я не понял когда, как и для чего используется метод, предоставляющий схему. Непонятно как её наличие влияет на процесс и чем/как она станет управлять. В моём случае, я не вижу отличий в результате сериализации со схемой и без неё (return null).

В моём случае ReadXml() вызывается кодом десериализации при состоянии reader'a, который указывает на элемент внутри родительского, что делает недоступными атрибуты, которые я рендерил во WriteXml(). Для того, чтобы сделать значения этих атрибутов доступными, удовлетворить существующую схему, используемую при валидации (которую мне вряд ли дадут просто так изменить), мне пришлось продублировать эти же атрибуты.

Мне было бы интересно услышать/прочитать мнение бывалых и/или указание на материалы, посвященные этой теме.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.