JavaBlog.fr / Java.lu C#,DEVELOPMENT CSharp/C# : Generate Custom Types from XSD file, XmlSerializer, XML Validation

CSharp/C# : Generate Custom Types from XSD file, XmlSerializer, XML Validation

Hi,

A post with concrete examples concerning the generation of Types/POJO from a XSD file, the serialization of these objects/POJO to XML and finally the validation of XML with XSD.

Generate Custom Types from XSD file

  • XSD file myXsdFile.xsd:
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                targetNamespace="urn:books"
                xmlns:bks="urn:books">
    
      <xsd:element name="books" type="bks:BooksForm"/>
    
      <xsd:complexType name="BooksForm">
        <xsd:sequence>
          <xsd:element name="book"
                      type="bks:BookForm"
                      minOccurs="0"
                      maxOccurs="unbounded"/>
        </xsd:sequence>
      </xsd:complexType>
    
      <xsd:complexType name="BookForm">
        <xsd:sequence>
          <xsd:element name="author"   type="xsd:string"/>
          <xsd:element name="title"    type="xsd:string"/>
          <xsd:element name="genre"    type="xsd:string"/>
          <xsd:element name="price"    type="xsd:float" />
          <xsd:element name="pub_date" type="xsd:date" />
          <xsd:element name="review"   type="xsd:string"/>
        </xsd:sequence>
        <xsd:attribute name="id"   type="xsd:string"/>
      </xsd:complexType>
    </xsd:schema>
    

     

  • CSharp sources and types generator:
            /// <summary>
            /// Custom Types Generator from XSD file
            /// </summary>
            /// <param name="xsdFile"></param>
            /// <param name="outputFile"></param>
            private static bool generateCSharpFile(string xsdFile, string outputFile)
            {
                bool result = true;
                try
                {
                    var stream = new MemoryStream(File.ReadAllBytes(xsdFile));
    
                    var schema = XmlSchema.Read(XmlReader.Create(stream), null);
                    var schemas = new XmlSchemas();
                    schemas.Add(schema);
    
                    var ns = new CodeNamespace { Name = "books" };
                    ns.Imports.Add(new CodeNamespaceImport("System"));
                    ns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
    
                    var exporter = new XmlCodeExporter(ns);
                    var importer = new XmlSchemaImporter(schemas);
    
                    foreach (XmlSchemaElement element in schema.Elements.Values)
                    {
                        var mapping = importer.ImportTypeMapping(element.QualifiedName);
                        exporter.ExportTypeMapping(mapping);
                    }
    
                    // Transform CodeDOM as required, adding new attributes, methods, modifying
                    // inheritance hierarchy, whatever.
                    var provider = new CSharpCodeProvider();
    
                    using (var writer = new StreamWriter(outputFile, false))
                    {
                        // Creates a new CodeGeneratorOptions.
                        CodeGeneratorOptions genOptions = new CodeGeneratorOptions();
    
                        // Sets a value indicating that the code generator should insert blank lines between type members.
                        genOptions.BlankLinesBetweenMembers = true;
    
                        // Sets the style of bracing format to use: either "Block" to start a
                        // bracing block on the same line as the declaration of its container, or 
                        // "C" to start the bracing for the block on the following line.
                        genOptions.BracingStyle = "C";
    
                        // Sets a value indicating that the code generator should not append an else, 
                        // catch or finally block, including brackets, at the closing line of a preceeding if or try block.
                        genOptions.ElseOnClosing = false;
    
                        // Sets the string to indent each line with.
                        genOptions.IndentString = "    ";
    
                        // Uses the CodeGeneratorOptions indexer property to set an
                        // example object to the type's string-keyed ListDictionary.
                        // Custom ICodeGenerator implementations can use objects 
                        // in this dictionary to customize process behavior.
                        genOptions["CustomGeneratorOptionStringExampleID"] = "BuildFlags: /A /B /C /D /E";
    
                        provider.GenerateCodeFromNamespace(ns, writer, genOptions);
                    }
                }
                catch (Exception ex)
                {
                    Console.Write(ex.ToString());
                    result = false;
                }
    
                return result;
            }
    
    

    //….

                string xsdFile = "C:\\Workspaces\\MS_Visual_Studio_Projects\\TestApps\\TestXmlXsd1\\myXsdFile.xsd";
                string outputFile = "C:\\Workspaces\\MS_Visual_Studio_Projects\\TestApps\\TestXmlXsd1\\generated\\MyCustomTypes.cs";
    
                generateCSharpFile(xsdFile, outputFile);
    

     
     

  • After execution, a CSharp file MyCustomTypes.cs containing all types of XSD file is generated:
    namespace books
    {
        using System;
        using System.Collections.Generic;
        
        
        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("TestXmlXsd1", "1.0.0.0")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:books")]
        [System.Xml.Serialization.XmlRootAttribute("books", Namespace="urn:books", IsNullable=false)]
        public partial class BooksForm
        {
            
            private BookForm[] bookField;
            
            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute("book", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
            public BookForm[] book
            {
                get
                {
                    return this.bookField;
                }
                set
                {
                    this.bookField = value;
                }
            }
        }
        
        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("TestXmlXsd1", "1.0.0.0")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:books")]
        public partial class BookForm
        {
            
            private string authorField;
            
            private string titleField;
            
            private string genreField;
            
            private float priceField;
            
            private System.DateTime pub_dateField;
            
            private string reviewField;
            
            private string idField;
            
            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
            public string author
            {
                get
                {
                    return this.authorField;
                }
                set
                {
                    this.authorField = value;
                }
            }
            
            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
            public string title
            {
                get
                {
                    return this.titleField;
                }
                set
                {
                    this.titleField = value;
                }
            }
            
            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
            public string genre
            {
                get
                {
                    return this.genreField;
                }
                set
                {
                    this.genreField = value;
                }
            }
            
            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
            public float price
            {
                get
                {
                    return this.priceField;
                }
                set
                {
                    this.priceField = value;
                }
            }
            
            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, DataType="date")]
            public System.DateTime pub_date
            {
                get
                {
                    return this.pub_dateField;
                }
                set
                {
                    this.pub_dateField = value;
                }
            }
            
            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
            public string review
            {
                get
                {
                    return this.reviewField;
                }
                set
                {
                    this.reviewField = value;
                }
            }
            
            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string id
            {
                get
                {
                    return this.idField;
                }
                set
                {
                    this.idField = value;
                }
            }
        }
    }
    
    

 
 
 

Serialization of objects to XML

  • Instantiation of POJO objects and use of them in order to generate XML file myXmlFile.xml:
            /// <summary>
            /// Generate XML file for POJO annotated (System.Xml)
            /// </summary>
            /// <param name="model"></param>
            /// <param name="xmlFile"></param>
            private static bool generateXML(object model, string xmlFile)
            {
                bool result = true;
                try
                {
                    // Build POJO
                    var serializer = new XmlSerializer(model.GetType());
    
                    using (StreamWriter writer = new StreamWriter(xmlFile, true, new UTF8Encoding(false)))
                    {
                        serializer.Serialize(writer, model);
                    }
                }
                catch (XmlSchemaValidationException ex)
                {
                    Console.Write(ex.ToString());
                    result = false;
                }
    
                return result;
            }
    

    //….

                string xmlGeneratedFile = "C:\\Workspaces\\MS_Visual_Studio_Projects\\TestApps\\TestXmlXsd1\\myXmlFile.xml";
                BooksForm booksForm = new BooksForm();
                {
                    List<BookForm> booksList = new List<BookForm>();
                    {
                        BookForm book = new BookForm();
                        book.id = "bk001";
                        book.author = "Writer";
                        book.title = "The First Book";
                        book.genre = "Fiction";
                        book.price = 44.95F;
                        book.pub_date = DateTime.ParseExact("2000-10-01", "yyyy-MM-dd", CultureInfo.InvariantCulture);
                        book.review = "An amazing story of nothing.";
                        booksList.Add(book);
                    }
                    {
                        BookForm book = new BookForm();
                        book.id = "bk002";
                        book.author = "Poet";
                        book.title = "The Poet's First Poem";
                        book.genre = "Poem";
                        book.price = 24.95F;
                        book.review = "Least poetic poems.";
                        booksList.Add(book);
                    }
                    booksForm.book = booksList.ToArray();
                }
    
    
                generateXML(booksForm, xmlGeneratedFile);
    

     
     

  • The generated XML file myXmlFile.xml would be:
    <?xml version="1.0" encoding="utf-8"?>
    <books xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:books">
      <book id="bk001" xmlns="">
        <author>Writer</author>
        <title>The First Book</title>
        <genre>Fiction</genre>
        <price>44.95</price>
        <pub_date>2000-10-01</pub_date>
        <review>An amazing story of nothing.</review>
      </book>
      <book id="bk002" xmlns="">
        <author>Poet</author>
        <title>The Poet's First Poem</title>
        <genre>Poem</genre>
        <price>24.95</price>
        <pub_date>0001-01-01</pub_date>
        <review>Least poetic poems.</review>
      </book>
    </books>
    

 
 
 

Validation of XML with XSD file

  • Validation of generated XML myXmlFile.xml with original XSD file myXsdFile.xml:
            /// <summary>
            /// Validate XML file with XSD file
            /// </summary>
            /// <param name="xmlFilePath"></param>
            /// <param name="xsdFilePath"></param>
            /// <param name="namespaceName"></param>
            /// <returns></returns>
            private static bool IsValidXml(string xmlFilePath, string xsdFilePath, string namespaceName)
            {
                var xdoc = XDocument.Load(xmlFilePath);
                var schemas = new XmlSchemaSet();
                schemas.Add(namespaceName, xsdFilePath);
    
                bool result = true;
                try
                {
                    xdoc.Validate(schemas, (sender, e) =>
                    {
                        Console.Write("Error:" + e.Message);
                        result = false;
                    });
                }
                catch (XmlSchemaValidationException ex)
                {
                    Console.Write(ex.ToString());
                    result = false;
                }
                return result;
            }
    

    //….

                string xsdFile = "C:\\Workspaces\\MS_Visual_Studio_Projects\\TestApps\\TestXmlXsd1\\myXsdFile.xsd";
                string xmlGeneratedFile = "C:\\Workspaces\\MS_Visual_Studio_Projects\\TestApps\\TestXmlXsd1\\myXmlFile.xml";
    
                IsValidXml(xmlGeneratedFile, xsdFile, "urn:books");
    

 

Note: Below the import / using needed to these methods:

using Microsoft.CSharp;
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.Text;
using books;
using System.Collections.Generic;
using System.Globalization;

 

Best regards,

Huseyin OZVEREN

Leave a Reply

Your email address will not be published.

Time limit is exhausted. Please reload CAPTCHA.

Related Post