Каков наилучший способ создания XML-документа, соответствующего схеме XSD? - PullRequest
3 голосов
/ 19 июня 2009

У меня есть XSD, и я должен сгенерировать XML-документ для отправки клиентам компании, с которой я работаю. Отправленные мною документы будут проверены по этой схеме XSD.

Каков наилучший способ создания XML-документа, соответствующего схеме XSD? Я имею в виду, я ищу лучшие практики и тому подобное. Я новичок в этом, и в то время как "Googling" здесь и там, я нашел людей, использующих XmlTextWriter, DataSet.WriteXml и других.

  1. DataSet.WriteXml, кажется, не работает для меня. Вот что я сделал:

    var ds = new DataSet();
    ds.ReadXmlSchema(schemaFile);
    ds.Tables["TableName"].Rows.Add("", "", 78, true, DateTime.Now);
    ...
    ds.WriteXml("C:\\xml.xml");
    

    Я обнаружил, что он генерирует узел с NewDataSet, и узлы расположены не в правильном порядке.

  2. XmlTextWriter, я нахожу это немного длинным делом ... но я сделаю это, если другого выбора не будет.

Какой, по вашему мнению, лучший способ сделать это? Есть ли другие подходы, чтобы сделать это? Я бы поставил здесь схему, если бы она не была такой длинной и имела бы отношение к вопросу.

Ответы [ 4 ]

6 голосов
/ 19 июня 2009

Основной практикой в ​​.NET является использование XML Serialization .

В вашем случае я бы сделал это:

  • запустите xsd.exe на .XSD, чтобы сгенерировать исходный код для классов (xsd / c)
  • создайте ваше приложение, которое использует эти сгенерированные классы. Имейте в виду, что вы можете расширить эти классы с помощью техники «частичных классов»
  • в коде, создать экземпляр XmlSerializer и сериализовать экземпляры класса.

Пример:

С учетом этой схемы:

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Foo" nillable="true" type="Foo" />
  <xs:complexType name="Foo">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="Bar" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="1" name="Baz" type="UntypedArray" />
    </xs:sequence>
  </xs:complexType>


  <xs:complexType name="UntypedArray">
    <xs:choice minOccurs="1" maxOccurs="unbounded">
      <xs:element name="Type1" type="Type1"                 minOccurs="1" maxOccurs="1"/>
      <xs:any     namespace="##other" processContents="lax" minOccurs="1" maxOccurs="1"/>
    </xs:choice>
  </xs:complexType>


  <xs:complexType name="Type1" mixed="true">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="Child" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
</xs:schema>

xsd.exe генерирует этот исходный код:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)]
public partial class Foo {

    private string barField;

    private object[] bazField;

    /// <remarks/>
    public string Bar {
        get {
            return this.barField;
        }
        set {
            this.barField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlArrayItemAttribute("", typeof(System.Xml.XmlElement), IsNullable=false)]
    [System.Xml.Serialization.XmlArrayItemAttribute(typeof(Type1), IsNullable=false)]
    public object[] Baz {
        get {
            return this.bazField;
        }
        set {
            this.bazField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class Type1 {

    private string childField;

    private string[] textField;

    /// <remarks/>
    public string Child {
        get {
            return this.childField;
        }
        set {
            this.childField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlTextAttribute()]
    public string[] Text {
        get {
            return this.textField;
        }
        set {
            this.textField = value;
        }
    }
}

В вашем приложении вы можете создать экземпляр Foo, а затем сериализовать его следующим образом:

    Foo foo = new Foo();
    // ...populate foo here...
    var builder = new System.Text.StringBuilder();
    XmlSerializer s = new XmlSerializer(typeof(Foo));
    using ( var writer = System.Xml.XmlWriter.Create(builder))
    {
        s.Serialize(writer, foo, ns);
    }
    string rawXml = builder.ToString();

Этот пример сериализуется в строку. Конечно, вы можете сериализовать другие XmlWriters, вы можете записать в файл, в любой произвольный поток и так далее.

Обычно я настраиваю сериализацию, чтобы опустить декларацию XML, пропустить пространства имен xml по умолчанию и т. Д. Как это:

    Foo foo = new Foo();
    // ...populate foo here...
    var builder = new System.Text.StringBuilder();
    var settings = new System.Xml.XmlWriterSettings { OmitXmlDeclaration = true, Indent= true };
    var ns = new XmlSerializerNamespaces();
    ns.Add("","");
    XmlSerializer s = new XmlSerializer(typeof(Foo));
    using ( var writer = System.Xml.XmlWriter.Create(builder, settings))
    {
        s.Serialize(writer, foo, ns);
    }
    string rawXml = builder.ToString();

Вы также можете сделать обратное - сопоставить документ XML с графом объектов в памяти - используя XmlSerializer. Используйте метод десериализации.

2 голосов
/ 24 октября 2012

Такая отличная ссылка .. http://msdn.microsoft.com/en-us/library/x6c1kb0s%28v=vs.110%29.aspx

Я только что сгенерировал классы с полями для csharp:

Сначала вы открываете командную строку Visual Studio ( Programs-> VisualStudio-> VisualstudioTools-> VisualstudioCommandPrompt )

Затем перейдите в каталог вашего xsd-файла и выполните следующую команду:

xsd /classes /fields /language:CS MyXSDSCHEMAFILE.xsd

(замените MyXSDSCHEMAFILE.xsd на ваше имя файла xsd)

После того, как ваш файл CS создан, скопируйте его в папку вашего проекта, где находятся все остальные файлы CS, и добавьте его в проект в Visual Studio, щелкнув правой кнопкой мыши по проекту и добавив существующий элемент. После этого перейдите в сегмент кода, где вы хотите использовать свой класс, и инициализируйте его следующим образом (имя класса - это класс, созданный в файле cs):

classname myvariablename = new classname(); // so easy :)
// now you just fill with content
myvariablename.whatever.andever.field = "JaWerHatDasErfunden";// you just set a field

затем сериализовать как XML (тонны примеров в Интернете)

Полезный совет: Имейте в виду, что создание экземпляров не всегда является частью созданных классов xsd.
Убедитесь, что вы правильно создаете свои объекты, чтобы избежать исключений Null Pointer.

2 голосов
/ 19 июня 2009

Пост, который я написал недавно, может быть вам интересен. Мне пришлось поработать с BizTalk и обнаружил, что генерация моих классов из XSD с последующей сериализацией этого класса по проводам (ва-ля XML) работает довольно хорошо!

http://blog.andrewsiemer.com/archive/2008/04/30/accepting-xmldocuments-from-biztalk-de-serializing-them-to-xsd-generated-serializable.aspx

Это позволяет вам работать с данными как с классом и всеми льготами, которые сопровождают это. И это полностью позволяет вам обойти авторов XML!

0 голосов
/ 19 июня 2009

Вы можете создать XML и затем запустить его через Xml Schema Validator, который я написал .

...