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:
    01<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    02            targetNamespace="urn:books"
    03            xmlns:bks="urn:books">
    04 
    05  <xsd:element name="books" type="bks:BooksForm"/>
    06 
    07  <xsd:complexType name="BooksForm">
    08    <xsd:sequence>
    09      <xsd:element name="book"
    10                  type="bks:BookForm"
    11                  minOccurs="0"
    12                  maxOccurs="unbounded"/>
    13    </xsd:sequence>
    14  </xsd:complexType>
    15 
    16  <xsd:complexType name="BookForm">
    17    <xsd:sequence>
    18      <xsd:element name="author"   type="xsd:string"/>
    19      <xsd:element name="title"    type="xsd:string"/>
    20      <xsd:element name="genre"    type="xsd:string"/>
    21      <xsd:element name="price"    type="xsd:float" />
    22      <xsd:element name="pub_date" type="xsd:date" />
    23      <xsd:element name="review"   type="xsd:string"/>
    24    </xsd:sequence>
    25    <xsd:attribute name="id"   type="xsd:string"/>
    26  </xsd:complexType>
    27</xsd:schema>

     

  • CSharp sources and types generator:
    01/// <summary>
    02/// Custom Types Generator from XSD file
    03/// </summary>
    04/// <param name="xsdFile"></param>
    05/// <param name="outputFile"></param>
    06private static bool generateCSharpFile(string xsdFile, string outputFile)
    07{
    08    bool result = true;
    09    try
    10    {
    11        var stream = new MemoryStream(File.ReadAllBytes(xsdFile));
    12 
    13        var schema = XmlSchema.Read(XmlReader.Create(stream), null);
    14        var schemas = new XmlSchemas();
    15        schemas.Add(schema);
    16 
    17        var ns = new CodeNamespace { Name = "books" };
    18        ns.Imports.Add(new CodeNamespaceImport("System"));
    19        ns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
    20 
    21        var exporter = new XmlCodeExporter(ns);
    22        var importer = new XmlSchemaImporter(schemas);
    23 
    24        foreach (XmlSchemaElement element in schema.Elements.Values)
    25        {
    26            var mapping = importer.ImportTypeMapping(element.QualifiedName);
    27            exporter.ExportTypeMapping(mapping);
    28        }
    29 
    30        // Transform CodeDOM as required, adding new attributes, methods, modifying
    31        // inheritance hierarchy, whatever.
    32        var provider = new CSharpCodeProvider();
    33 
    34        using (var writer = new StreamWriter(outputFile, false))
    35        {
    36            // Creates a new CodeGeneratorOptions.
    37            CodeGeneratorOptions genOptions = new CodeGeneratorOptions();
    38 
    39            // Sets a value indicating that the code generator should insert blank lines between type members.
    40            genOptions.BlankLinesBetweenMembers = true;
    41 
    42            // Sets the style of bracing format to use: either "Block" to start a
    43            // bracing block on the same line as the declaration of its container, or
    44            // "C" to start the bracing for the block on the following line.
    45            genOptions.BracingStyle = "C";
    46 
    47            // Sets a value indicating that the code generator should not append an else,
    48            // catch or finally block, including brackets, at the closing line of a preceeding if or try block.
    49            genOptions.ElseOnClosing = false;
    50 
    51            // Sets the string to indent each line with.
    52            genOptions.IndentString = "    ";
    53 
    54            // Uses the CodeGeneratorOptions indexer property to set an
    55            // example object to the type's string-keyed ListDictionary.
    56            // Custom ICodeGenerator implementations can use objects
    57            // in this dictionary to customize process behavior.
    58            genOptions["CustomGeneratorOptionStringExampleID"] = "BuildFlags: /A /B /C /D /E";
    59 
    60            provider.GenerateCodeFromNamespace(ns, writer, genOptions);
    61        }
    62    }
    63    catch (Exception ex)
    64    {
    65        Console.Write(ex.ToString());
    66        result = false;
    67    }
    68 
    69    return result;
    70}

    //….

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

     
     

  • After execution, a CSharp file MyCustomTypes.cs containing all types of XSD file is generated:
    001namespace books
    002{
    003    using System;
    004    using System.Collections.Generic;
    005     
    006     
    007    /// <remarks/>
    008    [System.CodeDom.Compiler.GeneratedCodeAttribute("TestXmlXsd1", "1.0.0.0")]
    009    [System.SerializableAttribute()]
    010    [System.Diagnostics.DebuggerStepThroughAttribute()]
    011    [System.ComponentModel.DesignerCategoryAttribute("code")]
    012    [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:books")]
    013    [System.Xml.Serialization.XmlRootAttribute("books", Namespace="urn:books", IsNullable=false)]
    014    public partial class BooksForm
    015    {
    016         
    017        private BookForm[] bookField;
    018         
    019        /// <remarks/>
    020        [System.Xml.Serialization.XmlElementAttribute("book", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    021        public BookForm[] book
    022        {
    023            get
    024            {
    025                return this.bookField;
    026            }
    027            set
    028            {
    029                this.bookField = value;
    030            }
    031        }
    032    }
    033     
    034    /// <remarks/>
    035    [System.CodeDom.Compiler.GeneratedCodeAttribute("TestXmlXsd1", "1.0.0.0")]
    036    [System.SerializableAttribute()]
    037    [System.Diagnostics.DebuggerStepThroughAttribute()]
    038    [System.ComponentModel.DesignerCategoryAttribute("code")]
    039    [System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:books")]
    040    public partial class BookForm
    041    {
    042         
    043        private string authorField;
    044         
    045        private string titleField;
    046         
    047        private string genreField;
    048         
    049        private float priceField;
    050         
    051        private System.DateTime pub_dateField;
    052         
    053        private string reviewField;
    054         
    055        private string idField;
    056         
    057        /// <remarks/>
    058        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    059        public string author
    060        {
    061            get
    062            {
    063                return this.authorField;
    064            }
    065            set
    066            {
    067                this.authorField = value;
    068            }
    069        }
    070         
    071        /// <remarks/>
    072        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    073        public string title
    074        {
    075            get
    076            {
    077                return this.titleField;
    078            }
    079            set
    080            {
    081                this.titleField = value;
    082            }
    083        }
    084         
    085        /// <remarks/>
    086        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    087        public string genre
    088        {
    089            get
    090            {
    091                return this.genreField;
    092            }
    093            set
    094            {
    095                this.genreField = value;
    096            }
    097        }
    098         
    099        /// <remarks/>
    100        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    101        public float price
    102        {
    103            get
    104            {
    105                return this.priceField;
    106            }
    107            set
    108            {
    109                this.priceField = value;
    110            }
    111        }
    112         
    113        /// <remarks/>
    114        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, DataType="date")]
    115        public System.DateTime pub_date
    116        {
    117            get
    118            {
    119                return this.pub_dateField;
    120            }
    121            set
    122            {
    123                this.pub_dateField = value;
    124            }
    125        }
    126         
    127        /// <remarks/>
    128        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    129        public string review
    130        {
    131            get
    132            {
    133                return this.reviewField;
    134            }
    135            set
    136            {
    137                this.reviewField = value;
    138            }
    139        }
    140         
    141        /// <remarks/>
    142        [System.Xml.Serialization.XmlAttributeAttribute()]
    143        public string id
    144        {
    145            get
    146            {
    147                return this.idField;
    148            }
    149            set
    150            {
    151                this.idField = value;
    152            }
    153        }
    154    }
    155}

 
 
 

Serialization of objects to XML

  • Instantiation of POJO objects and use of them in order to generate XML file myXmlFile.xml:
    01/// <summary>
    02/// Generate XML file for POJO annotated (System.Xml)
    03/// </summary>
    04/// <param name="model"></param>
    05/// <param name="xmlFile"></param>
    06private static bool generateXML(object model, string xmlFile)
    07{
    08    bool result = true;
    09    try
    10    {
    11        // Build POJO
    12        var serializer = new XmlSerializer(model.GetType());
    13 
    14        using (StreamWriter writer = new StreamWriter(xmlFile, true, new UTF8Encoding(false)))
    15        {
    16            serializer.Serialize(writer, model);
    17        }
    18    }
    19    catch (XmlSchemaValidationException ex)
    20    {
    21        Console.Write(ex.ToString());
    22        result = false;
    23    }
    24 
    25    return result;
    26}

    //….

    01string xmlGeneratedFile = "C:\\Workspaces\\MS_Visual_Studio_Projects\\TestApps\\TestXmlXsd1\\myXmlFile.xml";
    02BooksForm booksForm = new BooksForm();
    03{
    04    List<BookForm> booksList = new List<BookForm>();
    05    {
    06        BookForm book = new BookForm();
    07        book.id = "bk001";
    08        book.author = "Writer";
    09        book.title = "The First Book";
    10        book.genre = "Fiction";
    11        book.price = 44.95F;
    12        book.pub_date = DateTime.ParseExact("2000-10-01", "yyyy-MM-dd", CultureInfo.InvariantCulture);
    13        book.review = "An amazing story of nothing.";
    14        booksList.Add(book);
    15    }
    16    {
    17        BookForm book = new BookForm();
    18        book.id = "bk002";
    19        book.author = "Poet";
    20        book.title = "The Poet's First Poem";
    21        book.genre = "Poem";
    22        book.price = 24.95F;
    23        book.review = "Least poetic poems.";
    24        booksList.Add(book);
    25    }
    26    booksForm.book = booksList.ToArray();
    27}
    28 
    29 
    30generateXML(booksForm, xmlGeneratedFile);

     
     

  • The generated XML file myXmlFile.xml would be:
    01<?xml version="1.0" encoding="utf-8"?>
    02<books xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:books">
    03  <book id="bk001" xmlns="">
    04    <author>Writer</author>
    05    <title>The First Book</title>
    06    <genre>Fiction</genre>
    07    <price>44.95</price>
    08    <pub_date>2000-10-01</pub_date>
    09    <review>An amazing story of nothing.</review>
    10  </book>
    11  <book id="bk002" xmlns="">
    12    <author>Poet</author>
    13    <title>The Poet's First Poem</title>
    14    <genre>Poem</genre>
    15    <price>24.95</price>
    16    <pub_date>0001-01-01</pub_date>
    17    <review>Least poetic poems.</review>
    18  </book>
    19</books>

 
 
 

Validation of XML with XSD file

  • Validation of generated XML myXmlFile.xml with original XSD file myXsdFile.xml:
    01/// <summary>
    02/// Validate XML file with XSD file
    03/// </summary>
    04/// <param name="xmlFilePath"></param>
    05/// <param name="xsdFilePath"></param>
    06/// <param name="namespaceName"></param>
    07/// <returns></returns>
    08private static bool IsValidXml(string xmlFilePath, string xsdFilePath, string namespaceName)
    09{
    10    var xdoc = XDocument.Load(xmlFilePath);
    11    var schemas = new XmlSchemaSet();
    12    schemas.Add(namespaceName, xsdFilePath);
    13 
    14    bool result = true;
    15    try
    16    {
    17        xdoc.Validate(schemas, (sender, e) =>
    18        {
    19            Console.Write("Error:" + e.Message);
    20            result = false;
    21        });
    22    }
    23    catch (XmlSchemaValidationException ex)
    24    {
    25        Console.Write(ex.ToString());
    26        result = false;
    27    }
    28    return result;
    29}

    //….

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

 

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

01using Microsoft.CSharp;
02using System;
03using System.CodeDom;
04using System.CodeDom.Compiler;
05using System.IO;
06using System.Xml;
07using System.Xml.Linq;
08using System.Xml.Schema;
09using System.Xml.Serialization;
10using System.Text;
11using books;
12using System.Collections.Generic;
13using 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