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