Справка по Xsd2Code - сгенерированный код не соответствует схеме - PullRequest
1 голос
/ 20 октября 2011

Возможно, я что-то делаю не так, но я создал простую схему тестирования:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="MyRoot">
    <xs:annotation>
        <xs:documentation>Comment describing your root element</xs:documentation>
    </xs:annotation>
    <xs:complexType>
        <xs:choice>
            <xs:element name="MyChildOne" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice>
                        <xs:element name="SubChild" minOccurs="0" maxOccurs="unbounded"/>
                    </xs:choice>
                    <xs:attribute name="SomeAttribute" type="xs:string"/>
                    <xs:attribute name="SomethingElse" type="xs:string"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="MyChildTwo" type="xs:string" maxOccurs="unbounded"/>
        </xs:choice>
    </xs:complexType>
</xs:element>

Один корень, два дочерних элемента (один необязательный).

Я запустил Xsd2Code из VS2010, и сгенерированный код создал два «корневых» класса (MyRoot и MyChildOne) без создания ожидаемого MyChildTwo.Я бы ожидал модель с MyRoot.MyChildOne ...

Вот сгенерированный код:

using System;
using System.Diagnostics;
using System.Xml.Serialization;
using System.Collections;
using System.Xml.Schema;
using System.ComponentModel;
using System.Collections.Generic;


public partial class MyRoot
{

    private List<object> itemsField;

    public MyRoot()
    {
        this.itemsField = new List<object>();
    }

    public List<object> Items
    {
        get
        {
            return this.itemsField;
        }
        set
        {
            this.itemsField = value;
        }
    }
}

public partial class MyRootMyChildOne
{

    private List<object> itemsField;

    private string someAttributeField;

    private string somethingElseField;

    public MyRootMyChildOne()
    {
        this.itemsField = new List<object>();
    }

    public List<object> Items
    {
        get
        {
            return this.itemsField;
        }
        set
        {
            this.itemsField = value;
        }
    }

    public string SomeAttribute
    {
        get
        {
            return this.someAttributeField;
        }
        set
        {
            this.someAttributeField = value;
        }
    }

    public string SomethingElse
    {
        get
        {
            return this.somethingElseField;
        }
        set
        {
            this.somethingElseField = value;
        }
    }
}

Я не понимаю, как я могу сериализовать это в действительный (схема соответствует)XML-файл ...

Спасибо, что сообщили мне об этом

Cos

1 Ответ

1 голос
/ 20 октября 2011

Если вы используете xsd.exe для генерации этого класса, он дает вам то же самое:

public partial class MyRoot {

    private object[] itemsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("MyChildOne", typeof(MyRootMyChildOne))]
    [System.Xml.Serialization.XmlElementAttribute("MyChildTwo", typeof(string))]
    public object[] Items {
        get {
            return this.itemsField;
        }
        set {
            this.itemsField = value;
        }
    }
}

За исключением использования известных объявлений типов:

[System.Xml.Serialization.XmlElementAttribute("MyChildTwo", typeof(string))]

Такэто имеет смысл, если вы думаете об этом.Поскольку ваш дочерний тип 2 является строкой, а строка - простым типом в XSD, вы можете добавить экземпляры System.String в свой массив Items и затем сериализовать это, используя приведенный выше код.Каждая строка будет заключена в узел <MyChildTwo/>.

ОБНОВЛЕНИЕ

Чтобы сделать эту работу, вы создаете свой тип, а затем используете XmlSerializer:

var root = new MyRoot();
root.Items = new object[2];
root.Items[0] = new MyRootMyChildOne { Items = new object[1], SomeAttribute = "test", SomethingElse = "test" };
root.Items[1] = "hello";

var ser = new XmlSerializer(typeof(MyRoot));
var memoryStream = new MemoryStream();
var xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
var streamReader = new StreamReader(memoryStream, Encoding.UTF8);
ser.Serialize(xmlTextWriter, root);
memoryStream.Position = 0;

string xml = streamReader.ReadToEnd();

Это дает нам следующий XML:

<MyRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <MyChildOne SomeAttribute="test" SomethingElse="test" />
    <MyChildTwo>hello</MyChildTwo>
</MyRoot>
...