/*
* XML Schema Editor
* This code may be freely modified and distributed.
*
* History:
*
* Version 1.0
* First release, Marc Clifton
*/
/*
* Version 1.0
*
* Quirks:
* 1. Clicking on node A while in the middle of editing node B results in the name being changed for node A (mouse down event handler sets the current node!)
* 2. After editing the schema in the text edit box, you MUST compile otherwise changes will be lost!
* 3. If the tree node doesn't match the schema object, there are blank lines in the XSD file which are causing synchronization problems. Select "Schema/Compile" from menu.
*
* Bugs:
* 1. Editing the name of a complex type adds a "name" to the CT, not the parent element
*
* Features:
* dynamically adjusts for global and local types
* dynamically creates complex types from elements
* selecting a tree node highlights the corresponding XML text
* compiler error window
* xml can be edited directly instead of using the tree
* creates and manages global types list as types are added and removed
* keyboard shortcuts:
* F2-edit node label
* Ctrl-A : add to schema at current node
* Ctrl-T : go to top of schema
* Ctrl-P : got to parent of current node
*
* Notes:
*
* Need to do:
*
* Missing features:
* Auto-scroll edit box to show selected node
* Remember selected node when compiling schema
* Implement XmlSchemaElement minOccurs and maxOccurs with GUI to enter values
* Implement XmlSchemaAttribute fixed and use with GUI to enter values
* Implement XmlSchemaGroup
* ...others?
*
*/
/*
* XML Schema Editor and Strongly-Typed Configuration Class Generator
* This code may be freely modified and distributed.
*
* History:
*
* Version 1.0
* First release, Song Gao
*/
/*
* Version 1.0
*
* Features:
* This is an extension to Marc Clifton's XML Schema Editor.
* In addition to the existing XML schema editing function,
* it can generate strongly-typed configuration class based on an XML schema.
*
* There're two ways to generate the strongly-typed configuration class:
* 1. Run this application to edit an XML schema and generate the corresponding
* strongly-typed configuration class from the interface.
* 2. Integrate into your VS project to generate the strongly-typed configuration class transparently
* behind the scene. This is done by calling this application through command line.
*
* Need to do:
* 1. it supports string, int and long type only, need to add support to other types such as bool and datetime
* 2. it can generate C# code only, need to add support to other languages such as VB.net
* 3. need to enhance exception handling code in the generated class to deliver more detailed error messages
*/
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Xml.Schema;
using System.Text;
using System.CodeDom;
using System.CodeDom.Compiler;
namespace ConfigClassGen
{
public class SchemaEditor : System.Windows.Forms.Form
{
#region data
private System.Windows.Forms.TreeView tvSchema;
private System.Windows.Forms.ContextMenu tvcmSchema;
private System.Windows.Forms.MenuItem mnuAddElement;
private System.ComponentModel.IContainer components;
private System.Windows.Forms.TextBox edSchema;
private System.Windows.Forms.MenuItem mnuAddSimpleType;
private System.Windows.Forms.MenuItem mnuAddComplexType;
private System.Windows.Forms.MainMenu mainMenu;
private System.Windows.Forms.MenuItem mnuFile;
private System.Windows.Forms.MenuItem mnuNew;
private System.Windows.Forms.MenuItem mnuOpen;
private System.Windows.Forms.MenuItem mnuSave;
private System.Windows.Forms.MenuItem mnuSaveAs;
private System.Windows.Forms.MenuItem mnuExit;
private System.Windows.Forms.MenuItem menuItem2;
private System.Windows.Forms.MenuItem menuItem3;
private System.Windows.Forms.MenuItem mnuAbout;
private System.Windows.Forms.OpenFileDialog openSchemaDialog;
private System.Windows.Forms.ImageList tvImageList;
private System.Windows.Forms.MenuItem mnuAddAnnotation;
private System.Windows.Forms.MenuItem mnuAddAttribute;
private System.Windows.Forms.TextBox edSchemaErrors;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.MenuItem mnuCompile;
private System.Windows.Forms.GroupBox gbSelectType;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.MenuItem menuItem4;
private System.Windows.Forms.MenuItem mnuRemoveNode;
private System.Windows.Forms.MenuItem menuItem6;
private System.Windows.Forms.MenuItem menuItem7;
private System.Windows.Forms.MenuItem menuItem5;
private System.Windows.Forms.MenuItem menuItem9;
private System.Windows.Forms.ComboBox cbGlobalTypes;
private System.Windows.Forms.ComboBox cbSimpleTypes;
private XmlSchema schema;
private System.Windows.Forms.MenuItem mnuFacetEnumeration;
private System.Windows.Forms.MenuItem mnuFacetMaxExclusive;
private System.Windows.Forms.MenuItem mnuFacetMaxInclusive;
private System.Windows.Forms.MenuItem mnuFacetMinExclusive;
private System.Windows.Forms.MenuItem mnuFacetMinInclusive;
private System.Windows.Forms.MenuItem mnuFacetNumeric;
private System.Windows.Forms.MenuItem mnuFacetPattern;
private System.Windows.Forms.MenuItem mnuFacetWhiteSpace;
private System.Windows.Forms.MenuItem mnuFacetFractionDigits;
private System.Windows.Forms.MenuItem mnuFacetLength;
private System.Windows.Forms.MenuItem mnuFacetMaxLength;
private System.Windows.Forms.MenuItem mnuFacetMinLength;
private System.Windows.Forms.MenuItem mnuFacetTotalDigits;
private System.Windows.Forms.MenuItem mnuAddDocumentation;
private System.Windows.Forms.MenuItem mnuAddAppInfo;
private string prevLabel;
private System.Windows.Forms.SaveFileDialog saveAsSchemaDialog;
private System.Windows.Forms.MenuItem menuItem8;
private string fileName = null;
enum TreeViewImages { Schema, Element, SimpleType, ComplexType, Annotation, Documentation, AppInfo, Attribute, Facet };
#endregion
private string outputFileName = null;
private string outputNamespace = null;
private StringBuilder sbOutput = new StringBuilder();
private StringBuilder sbField = new StringBuilder();
private StringBuilder sbProperty = new StringBuilder();
private StringBuilder sbLoadValue = new StringBuilder();
private CodeMemberMethod loadAppValuesMethod;
private CodeCompileUnit targetUnit;
private MenuItem menuItem10;
private bool flagTopElement = true;
#region GlobalElementType
public class GlobalElementType
{
public GlobalElementType(string name, XmlSchemaObject type)
{
this.name = name;
this.type = type;
}
public override string ToString()
{
return name;
}
public string Get()
{
return name;
}
public void Set(string name)
{
this.name = name;
}
public string name;
public XmlSchemaObject type;
}
#endregion
#region SchemaEditor Class
public SchemaEditor(string _InputFileName, string _OutputFileName, string _outputNamespace)
: this()
{
fileName = _InputFileName;
outputFileName = _OutputFileName;
outputNamespace = _outputNamespace;
}
public SchemaEditor(string _InputFileName, string _OutputFileName)
: this()
{
fileName = _InputFileName;
outputFileName = _OutputFileName;
}
public SchemaEditor(string _InputFileName)
: this()
{
fileName = _InputFileName;
}
public SchemaEditor()
{
InitializeComponent();
CreateRootNode();
tvSchema.LabelEdit = true;
tvSchema.KeyUp += new KeyEventHandler(EventTreeViewKeyUp);
tvSchema.BeforeLabelEdit += new NodeLabelEditEventHandler(PreEventLabelChanged);
tvSchema.AfterLabelEdit += new NodeLabelEditEventHandler(EventLabelChanged);
tvSchema.MouseDown += new MouseEventHandler(EventMouseDown);
edSchema.LostFocus += new EventHandler(EventSchemaTextBoxLostFocus);
schema = new XmlSchema();
CompileSchema();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
[STAThread]
static void Main(string[] args)
{
if (args.Length >= 3)
Application.Run(new SchemaEditor(args[0], args[1], args[2]));
else if (args.Length >= 2)
Application.Run(new SchemaEditor(args[0], args[1]));
else if (args.Length >= 1)
Application.Run(new SchemaEditor(args[0]));
else
Application.Run(new SchemaEditor());
}
#endregion
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SchemaEditor));
this.tvSchema = new System.Windows.Forms.TreeView();
this.tvcmSchema = new System.Windows.Forms.ContextMenu();
this.mnuAddElement = new System.Windows.Forms.MenuItem();
this.mnuAddSimpleType = new System.Windows.Forms.MenuItem();
this.mnuAddComplexType = new System.Windows.Forms.MenuItem();
this.mnuAddAttribute = new System.Windows.Forms.MenuItem();
this.menuItem9 = new System.Windows.Forms.MenuItem();
this.menuItem5 = new System.Windows.Forms.MenuItem();
this.mnuAddAnnotation = new System.Windows.Forms.MenuItem();
this.mnuAddDocumentation = new System.Windows.Forms.MenuItem();
this.mnuAddAppInfo = new System.Windows.Forms.MenuItem();
this.menuItem4 = new System.Windows.Forms.MenuItem();
this.menuItem7 = new System.Windows.Forms.MenuItem();
this.mnuFacetEnumeration = new System.Windows.Forms.MenuItem();
this.mnuFacetMaxExclusive = new System.Windows.Forms.MenuItem();
this.mnuFacetMaxInclusive = new System.Windows.Forms.MenuItem();
this.mnuFacetMinExclusive = new System.Windows.Forms.MenuItem();
this.mnuFacetMinInclusive = new System.Windows.Forms.MenuItem();
this.mnuFacetNumeric = new System.Windows.Forms.MenuItem();
this.mnuFacetFractionDigits = new System.Windows.Forms.MenuItem();
this.mnuFacetLength = new System.Windows.Forms.MenuItem();
this.mnuFacetMaxLength = new System.Windows.Forms.MenuItem();
this.mnuFacetMinLength = new System.Windows.Forms.MenuItem();
this.mnuFacetTotalDigits = new System.Windows.Forms.MenuItem();
this.mnuFacetPattern = new System.Windows.Forms.MenuItem();
this.mnuFacetWhiteSpace = new System.Windows.Forms.MenuItem();
this.menuItem6 = new System.Windows.Forms.MenuItem();
this.mnuRemoveNode = new System.Windows.Forms.MenuItem();
this.tvImageList = new System.Windows.Forms.ImageList(this.components);
this.edSchema = new System.Windows.Forms.TextBox();
this.mainMenu = new System.Windows.Forms.MainMenu(this.components);
this.mnuFile = new System.Windows.Forms.MenuItem();
this.mnuNew = new System.Windows.Forms.MenuItem();
this.mnuOpen = new System.Windows.Forms.MenuItem();
this.menuItem3 = new System.Windows.Forms.MenuItem();
this.mnuSave = new System.Windows.Forms.MenuItem();
this.mnuSaveAs = new System.Windows.Forms.MenuItem();
this.menuItem2 = new System.Windows.Forms.MenuItem();
this.mnuExit = new System.Windows.Forms.MenuItem();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.mnuCompile = new System.Windows.Forms.MenuItem();
this.menuItem8 = new System.Windows.Forms.MenuItem();
this.menuItem10 = new System.Windows.Forms.MenuItem();
this.mnuAbout = new System.Windows.Forms.MenuItem();
this.openSchemaDialog = new System.Windows.Forms.OpenFileDialog();
this.edSchemaErrors = new System.Windows.Forms.TextBox();
this.gbSelectType = new System.Windows.Forms.GroupBox();
this.cbGlobalTypes = new System.Windows.Forms.ComboBox();
this.cbSimpleTypes = new System.Windows.Forms.ComboBox();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.saveAsSchemaDialog = new System.Windows.Forms.SaveFileDialog();
this.gbSelectType.SuspendLayout();
this.SuspendLayout();
//
// tvSchema
//
this.tvSchema.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.tvSchema.ContextMenu = this.tvcmSchema;
this.tvSchema.FullRowSelect = true;
this.tvSchema.HideSelection = false;
this.tvSchema.ImageIndex = 0;
this.tvSchema.ImageList = this.tvImageList;
this.tvSchema.Location = new System.Drawing.Point(8, 8);
this.tvSchema.Name = "tvSchema";
this.tvSchema.SelectedImageIndex = 0;
this.tvSchema.Size = new System.Drawing.Size(280, 432);
this.tvSchema.TabIndex = 0;
this.tvSchema.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvSchema_AfterSelect);
//
// tvcmSchema
//
this.tvcmSchema.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mnuAddElement,
this.mnuAddSimpleType,
this.mnuAddComplexType,
this.mnuAddAttribute,
this.menuItem9,
this.menuItem5,
this.menuItem4,
this.menuItem7,
this.menuItem6,
this.mnuRemoveNode});
//
// mnuAddElement
//
this.mnuAddElement.Index = 0;
this.mnuAddElement.Text = "Element";
this.mnuAddElement.Click += new System.EventHandler(this.mnuAddElement_Click);
//
// mnuAddSimpleType
//
this.mnuAddSimpleType.Index = 1;
this.mnuAddSimpleType.Text = "Simple Type";
this.mnuAddSimpleType.Click += new System.EventHandler(this.mnuAddSimpleType_Click);
//
// mnuAddComplexType
//
this.mnuAddComplexType.Index = 2;
this.mnuAddComplexType.Text = "Complex Type";
this.mnuAddComplexType.Click += new System.EventHandler(this.mnuAddComplexType_Click);
//
// mnuAddAttribute
//
this.mnuAddAttribute.Index = 3;
this.mnuAddAttribute.Text = "Attribute";
this.mnuAddAttribute.Click += new System.EventHandler(this.mnuAddAttribute_Click);
//
// menuItem9
//
this.menuItem9.Index = 4;
this.menuItem9.Text = "-";
//
// menuItem5
//
this.menuItem5.Index = 5;
this.menuItem5.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mnuAddAnnotation,
this.mnuAddDocumentation,
this.mnuAddAppInfo});
this.menuItem5.Text = "Annotation";
//
// mnuAddAnnotation
//
this.mnuAddAnnotation.Index = 0;
this.mnuAddAnnotation.Text = "Annotation";
this.mnuAddAnnotation.Click += new System.EventHandler(this.mnuAddAnnotation_Click);
//
// mnuAddDocumentation
//
this.mnuAddDocumentation.Index = 1;
this.mnuAddDocumentation.Text = "Documentation";
this.mnuAddDocumentation.Click += new System.EventHandler(this.mnuAddDocumentation_Click);
//
// mnuAddAppInfo
//
this.mnuAddAppInfo.Index = 2;
this.mnuAddAppInfo.Text = "App Info";
this.mnuAddAppInfo.Click += new System.EventHandler(this.mnuAddAppInfo_Click);
//
// menuItem4
//
this.menuItem4.Index = 6;
this.menuItem4.Text = "-";
//
// menuItem7
//
this.menuItem7.Index = 7;
this.menuItem7.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mnuFacetEnumeration,
this.mnuFacetMaxExclusive,
this.mnuFacetMaxInclusive,
this.mnuFacetMinExclusive,
this.mnuFacetMinInclusive,
this.mnuFacetNumeric,
this.mnuFacetPattern,
this.mnuFacetWhiteSpace});
this.menuItem7.Text = "Facet";
//
// mnuFacetEnumeration
//
this.mnuFacetEnumeration.Index = 0;
this.mnuFacetEnumeration.Text = "Enumeration";
this.mnuFacetEnumeration.Click += new System.EventHandler(this.mnuFacetEnumeration_Click);
//
// mnuFacetMaxExclusive
//
this.mnuFacetMaxExclusive.Index = 1;
this.mnuFacetMaxExclusive.Text = "Max Exclusive";
this.mnuFacetMaxExclusive.Click += new System.EventHandler(this.mnuFacetMaxExclusive_Click);
//
// mnuFacetMaxInclusive
//
this.mnuFacetMaxInclusive.Index = 2;
this.mnuFacetMaxInclusive.Text = "Max Inclusive";
this.mnuFacetMaxInclusive.Click += new System.EventHandler(this.mnuFacetMaxInclusive_Click);
//
// mnuFacetMinExclusive
//
this.mnuFacetMinExclusive.Index = 3;
this.mnuFacetMinExclusive.Text = "Min Exclusive";
this.mnuFacetMinExclusive.Click += new System.EventHandler(this.mnuFacetMinExclusive_Click);
//
// mnuFacetMinInclusive
//
this.mnuFacetMinInclusive.Index = 4;
this.mnuFacetMinInclusive.Text = "Min Inclusive";
this.mnuFacetMinInclusive.Click += new System.EventHandler(this.mnuFacetMinInclusive_Click);
//
// mnuFacetNumeric
//
this.mnuFacetNumeric.Index = 5;
this.mnuFacetNumeric.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mnuFacetFractionDigits,
this.mnuFacetLength,
this.mnuFacetMaxLength,
this.mnuFacetMinLength,
this.mnuFacetTotalDigits});
this.mnuFacetNumeric.Text = "Numeric";
//
// mnuFacetFractionDigits
//
this.mnuFacetFractionDigits.Index = 0;
this.mnuFacetFractionDigits.Text = "Fraction Digits";
this.mnuFacetFractionDigits.Click += new System.EventHandler(this.mnuFacetFractionDigits_Click);
//
// mnuFacetLength
//
this.mnuFacetLength.Index = 1;
this.mnuFacetLength.Text = "Length";
this.mnuFacetLength.Click += new System.EventHandler(this.mnuFacetLength_Click);
//
// mnuFacetMaxLength
//
this.mnuFacetMaxLength.Index = 2;
this.mnuFacetMaxLength.Text = "Max Length";
this.mnuFacetMaxLength.Click += new System.EventHandler(this.mnuFacetMaxLength_Click);
//
// mnuFacetMinLength
//
this.mnuFacetMinLength.Index = 3;
this.mnuFacetMinLength.Text = "Min Length";
this.mnuFacetMinLength.Click += new System.EventHandler(this.mnuFacetMinLength_Click);
//
// mnuFacetTotalDigits
//
this.mnuFacetTotalDigits.Index = 4;
this.mnuFacetTotalDigits.Text = "Total Digits";
this.mnuFacetTotalDigits.Click += new System.EventHandler(this.mnuFacetTotalDigits_Click);
//
// mnuFacetPattern
//
this.mnuFacetPattern.Index = 6;
this.mnuFacetPattern.Text = "Pattern";
this.mnuFacetPattern.Click += new System.EventHandler(this.mnuFacetPattern_Click);
//
// mnuFacetWhiteSpace
//
this.mnuFacetWhiteSpace.Index = 7;
this.mnuFacetWhiteSpace.Text = "White Space";
this.mnuFacetWhiteSpace.Click += new System.EventHandler(this.mnuFacetWhiteSpace_Click);
//
// menuItem6
//
this.menuItem6.Index = 8;
this.menuItem6.Text = "-";
//
// mnuRemoveNode
//
this.mnuRemoveNode.Index = 9;
this.mnuRemoveNode.Text = "Remove";
this.mnuRemoveNode.Click += new System.EventHandler(this.mnuRemoveNode_Click);
//
// tvImageList
//
this.tvImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("tvImageList.ImageStream")));
this.tvImageList.TransparentColor = System.Drawing.Color.Transparent;
this.tvImageList.Images.SetKeyName(0, "");
this.tvImageList.Images.SetKeyName(1, "");
this.tvImageList.Images.SetKeyName(2, "");
this.tvImageList.Images.SetKeyName(3, "");
this.tvImageList.Images.SetKeyName(4, "");
this.tvImageList.Images.SetKeyName(5, "");
this.tvImageList.Images.SetKeyName(6, "");
this.tvImageList.Images.SetKeyName(7, "");
this.tvImageList.Images.SetKeyName(8, "");
//
// edSchema
//
this.edSchema.AcceptsReturn = true;
this.edSchema.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.edSchema.HideSelection = false;
this.edSchema.Location = new System.Drawing.Point(296, 8);
this.edSchema.Multiline = true;
this.edSchema.Name = "edSchema";
this.edSchema.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.edSchema.Size = new System.Drawing.Size(640, 432);
this.edSchema.TabIndex = 1;
this.edSchema.WordWrap = false;
//
// mainMenu
//
this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mnuFile,
this.menuItem1,
this.mnuAbout});
//
// mnuFile
//
this.mnuFile.Index = 0;
this.mnuFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mnuNew,
this.mnuOpen,
this.menuItem3,
this.mnuSave,
this.mnuSaveAs,
this.menuItem2,
this.mnuExit});
this.mnuFile.Text = "&File";
//
// mnuNew
//
this.mnuNew.Index = 0;
this.mnuNew.Text = "&New";
this.mnuNew.Click += new System.EventHandler(this.mnuNew_Click);
//
// mnuOpen
//
this.mnuOpen.Index = 1;
this.mnuOpen.Text = "&Open";
this.mnuOpen.Click += new System.EventHandler(this.mnuOpen_Click);
//
// menuItem3
//
this.menuItem3.Index = 2;
this.menuItem3.Text = "-";
//
// mnuSave
//
this.mnuSave.Index = 3;
this.mnuSave.Text = "&Save";
this.mnuSave.Click += new System.EventHandler(this.mnuSave_Click);
//
// mnuSaveAs
//
this.mnuSaveAs.Index = 4;
this.mnuSaveAs.Text = "Save &As";
this.mnuSaveAs.Click += new System.EventHandler(this.mnuSaveAs_Click);
//
// menuItem2
//
this.menuItem2.Index = 5;
this.menuItem2.Text = "-";
//
// mnuExit
//
this.mnuExit.Index = 6;
this.mnuExit.Text = "E&xit";
this.mnuExit.Click += new System.EventHandler(this.mnuExit_Click);
//
// menuItem1
//
this.menuItem1.Index = 1;
this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.mnuCompile,
this.menuItem8,
this.menuItem10});
this.menuItem1.Text = "&Schema";
//
// mnuCompile
//
this.mnuCompile.Index = 0;
this.mnuCompile.Text = "&Compile";
this.mnuCompile.Click += new System.EventHandler(this.mnuCompile_Click);
//
// menuItem8
//
this.menuItem8.Index = 1;
this.menuItem8.Text = "Generate Code";
this.menuItem8.Click += new System.EventHandler(this.menuItem8_Click);
//
// menuItem10
//
this.menuItem10.Index = 2;
this.menuItem10.Text = "Config Class Namespace...";
this.menuItem10.Click += new System.EventHandler(this.menuItem10_Click);
//
// mnuAbout
//
this.mnuAbout.Index = 2;
this.mnuAbout.Text = "&About";
this.mnuAbout.Click += new System.EventHandler(this.mnuAbout_Click);
//
// edSchemaErrors
//
this.edSchemaErrors.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.edSchemaErrors.HideSelection = false;
this.edSchemaErrors.Location = new System.Drawing.Point(296, 448);
this.edSchemaErrors.Multiline = true;
this.edSchemaErrors.Name = "edSchemaErrors";
this.edSchemaErrors.ReadOnly = true;
this.edSchemaErrors.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.edSchemaErrors.Size = new System.Drawing.Size(640, 88);
this.edSchemaErrors.TabIndex = 2;
//
// gbSelectType
//
this.gbSelectType.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.gbSelectType.Controls.Add(this.cbGlobalTypes);
this.gbSelectType.Controls.Add(this.cbSimpleTypes);
this.gbSelectType.Controls.Add(this.label2);
this.gbSelectType.Controls.Add(this.label1);
this.gbSelectType.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.gbSelectType.Location = new System.Drawing.Point(8, 440);
this.gbSelectType.Name = "gbSelectType";
this.gbSelectType.Size = new System.Drawing.Size(280, 96);
this.gbSelectType.TabIndex = 3;
this.gbSelectType.TabStop = false;
this.gbSelectType.Text = "Select Type";
//
// cbGlobalTypes
//
this.cbGlobalTypes.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.cbGlobalTypes.Location = new System.Drawing.Point(88, 56);
this.cbGlobalTypes.Name = "cbGlobalTypes";
this.cbGlobalTypes.Size = new System.Drawing.Size(168, 21);
this.cbGlobalTypes.Sorted = true;
this.cbGlobalTypes.TabIndex = 3;
this.cbGlobalTypes.SelectedIndexChanged += new System.EventHandler(this.cbGlobalTypes_SelectedIndexChanged);
//
// cbSimpleTypes
//
this.cbSimpleTypes.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.cbSimpleTypes.Items.AddRange(new object[] {
"anyURI",
"base64Binary",
"boolean",
"byte",
"date",
"dateTime",
"decimal",
"double",
"duration",
"ENTITIY",
"float",
"gDay",
"gMonth",
"gMonthDay",
"gYear",
"gYearMonth",
"hexBinary",
"ID",
"IDREF",
"imteger",
"int",
"language",
"long",
"Name",
"NCName",
"negativeInteger",
"NMTOKEN",
"nonNegativeInteger",
"nonPositiveInteger",
"normalizedString",
"NOTATION",
"positiveInteger",
"QName",
"short",
"string",
"time",
"token",
"unsignedByte",
"unsignedInt",
"unsignedLong",
"unsignedShort"});
this.cbSimpleTypes.Location = new System.Drawing.Point(88, 24);
this.cbSimpleTypes.Name = "cbSimpleTypes";
this.cbSimpleTypes.Size = new System.Drawing.Size(168, 21);
this.cbSimpleTypes.Sorted = true;
this.cbSimpleTypes.TabIndex = 2;
this.cbSimpleTypes.SelectedIndexChanged += new System.EventHandler(this.cbSimpleTypes_SelectedIndexChanged);
//
// label2
//
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.Location = new System.Drawing.Point(8, 58);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(80, 16);
this.label2.TabIndex = 1;
this.label2.Text = "Global Types:";
//
// label1
//
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.Location = new System.Drawing.Point(8, 26);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(80, 16);
this.label1.TabIndex = 0;
this.label1.Text = "Simple Types:";
//
// saveAsSchemaDialog
//
this.saveAsSchemaDialog.DefaultExt = "xsd";
//
// SchemaEditor
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(944, 553);
this.Controls.Add(this.gbSelectType);
this.Controls.Add(this.edSchemaErrors);
this.Controls.Add(this.edSchema);
this.Controls.Add(this.tvSchema);
this.Menu = this.mainMenu;
this.Name = "SchemaEditor";
this.Text = "XML Schema Editor and Configuration Class Generator";
this.Load += new System.EventHandler(this.SchemaEditor_Load);
this.gbSelectType.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
#region Menu Commands
#region Add Facets
// There are several types of facets that can be added to a simple type.
// This code adds a facet and specifies a default value (completely arbitrary)
private void mnuFacetEnumeration_Click(object sender, System.EventArgs e)
{
bool ret = AddFacet(new XmlSchemaEnumerationFacet(), "1", TreeViewImages.Facet);
if (!ret)
{
MessageBox.Show("Cannot add an element to this item.");
}
}
private void mnuFacetMaxExclusive_Click(object sender, System.EventArgs e)
{
bool ret = AddFacet(new XmlSchemaMaxExclusiveFacet(), "101", TreeViewImages.Facet);
if (!ret)
{
MessageBox.Show("Cannot add an element to this item.");
}
}
private void mnuFacetMaxInclusive_Click(object sender, System.EventArgs e)
{
bool ret = AddFacet(new XmlSchemaMaxInclusiveFacet(), "100", TreeViewImages.Facet);
if (!ret)
{
MessageBox.Show("Cannot add an element to this item.");
}
}
private void mnuFacetMinExclusive_Click(object sender, System.EventArgs e)
{
bool ret = AddFacet(new XmlSchemaMinExclusiveFacet(), "0", TreeViewImages.Facet);
if (!ret)
{
MessageBox.Show("Cannot add an element to this item.");
}
}
private void mnuFacetMinInclusive_Click(object sender, System.EventArgs e)
{
bool ret = AddFacet(new XmlSchemaMinInclusiveFacet(), "1", TreeViewImages.Facet);
if (!ret)
{
MessageBox.Show("Cannot add an element to this item.");
}
}
private void mnuFacetFractionDigits_Click(object sender, System.EventArgs e)
{
bool ret = AddFacet(new XmlSchemaFractionDigitsFacet(), "2", TreeViewImages.Facet);
if (!ret)
{
MessageBox.Show("Cannot add an element to this item.");
}
}
private void mnuFacetLength_Click(object sender, System.EventArgs e)
{
bool ret = AddFacet(new XmlSchemaLengthFacet(), "16", TreeViewImages.Facet);
if (!ret)
{
MessageBox.Show("Cannot add an element to this item.");
}
}
private void mnuFacetMaxLength_Click(object sender, System.EventArgs e)
{
bool ret = AddFacet(new XmlSchemaMaxLengthFacet(), "16", TreeViewImages.Facet);
if (!ret)
{
MessageBox.Show("Cannot add an element to this item.");
}
}
private void mnuFacetMinLength_Click(object sender, System.EventArgs e)
{
bool ret = AddFacet(new XmlSchemaMinLengthFacet(), "1", TreeViewImages.Facet);
if (!ret)
{
MessageBox.Show("Cannot add an element to this item.");
}
}
private void mnuFacetTotalDigits_Click(object sender, System.EventArgs e)
{
bool ret = AddFacet(new XmlSchemaTotalDigitsFacet(), "8", TreeViewImages.Facet);
if (!ret)
{
MessageBox.Show("Cannot add an element to this item.");
}
}
private void mnuFacetPattern_Click(object sender, System.EventArgs e)
{
bool ret = AddFacet(new XmlSchemaPatternFacet(), "[0-9]", TreeViewImages.Facet);
if (!ret)
{
MessageBox.Show("Cannot add an element to this item.");
}
}
private void mnuFacetWhiteSpace_Click(object sender, System.EventArgs e)
{
bool ret = AddFacet(new XmlSchemaWhiteSpaceFacet(), "collapse", TreeViewImages.Facet);
if (!ret)
{
MessageBox.Show("Cannot add an element to this item.");
}
}
#endregion
#region Add Annotation, Documentation, and AppInfo
// create an annotation for the schema or for an annotatable object
private void mnuAddAnnotation_Click(object sender, System.EventArgs e)
{
XmlSchemaAnnotation annot = new XmlSchemaAnnotation();
TreeNode newNode = CreateNode("--annotation--");
// if adding at the schema root level...
if (newNode.Parent == tvSchema.Nodes[0])
{
AddToCollection(schema.Items, annot, newNode, TreeViewImages.Annotation);
}
else
{
// otherwise, get the object as an XmlSchemaAnnotated type
XmlSchemaAnnotated obj = newNode.Parent.Tag as XmlSchemaAnnotated;
if (obj != null)
{
// if it exists, add the annotation
obj.Annotation = annot;
newNode.Tag = annot;
newNode.ImageIndex = (int)TreeViewImages.Annotation;
newNode.SelectedImageIndex = (int)TreeViewImages.Annotation;
CompileSchema();
}
else
{
// otherwise, tell the user annotation cannot be added to this type.
newNode.Parent.Nodes.Remove(newNode);
MessageBox.Show("Cannot create an annotation for this item.");
}
}
}
private void mnuAddDocumentation_Click(object sender, System.EventArgs e)
{
bool success = false;
XmlSchemaAnnotation annot = tvSchema.SelectedNode.Tag as XmlSchemaAnnotation;
// if the parent node is an annotation type...
if (annot != null)
{
// ...then add the documentation type
TreeNode newNode = CreateNode("--documentation--");
XmlSchemaDocumentation doc = new XmlSchemaDocumentation();
doc.Markup = TextToNodeArray("Documentation");
annot.Items.Add(doc);
newNode.Tag = doc;
newNode.ImageIndex = (int)TreeViewImages.Annotation;
newNode.SelectedImageIndex = (int)TreeViewImages.Annotation;
CompileSchema();
success = true;
}
if (!success)
{
// otherwise create the annotation type first
mnuAddAnnotation_Click(sender, e);
annot = tvSchema.SelectedNode.Tag as XmlSchemaAnnotation;
// if successful in adding the annotation type, add the documentation type now
if (annot != null)
{
mnuAddDocumentation_Click(sender, e);
}
}
}
private void mnuAddAppInfo_Click(object sender, System.EventArgs e)
{
bool success = false;
XmlSchemaAnnotation annot = tvSchema.SelectedNode.Tag as XmlSchemaAnnotation;
// if the parent node is an annotation type...
if (annot != null)
{
// ...then add the AppInfo type
TreeNode newNode = CreateNode("--app info--");
XmlSchemaAppInfo doc = new XmlSchemaAppInfo();
doc.Markup = TextToNodeArray("Application Information");
annot.Items.Add(doc);
newNode.Tag = doc;
newNode.ImageIndex = (int)TreeViewImages.Annotation;
newNode.SelectedImageIndex = (int)TreeViewImages.Annotation;
CompileSchema();
success = true;
}
if (!success)
{
// otherwise create the annotation type first
mnuAddAnnotation_Click(sender, e);
annot = tvSchema.SelectedNode.Tag as XmlSchemaAnnotation;
// if successful in creating the annotation type, add the AppInfo type now
if (annot != null)
{
mnuAddAppInfo_Click(sender, e);
}
}
}
#endregion
#region Add Attribute
// Can only be added to schema root as a global or complex type.
// For complex types, the attribute can reference a global type.
// An optional type can be specified referring to a simple type.
// If the type isn't used, the attribute must define a simple type.
private void mnuAddAttribute_Click(object sender, System.EventArgs e)
{
TreeNode newNode = CreateNode("Attribute");
XmlSchemaAttribute attrib = new XmlSchemaAttribute();
attrib.Name = "Attribute";
attrib.SchemaTypeName = new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema");
// root node?
if (newNode.Parent == tvSchema.Nodes[0])
{
// add to root of schema. An global attribute cannot reference a global type
AddToCollection(schema.Items, attrib, newNode, TreeViewImages.Attribute);
cbGlobalTypes.Items.Add(new GlobalElementType(attrib.Name, attrib));
cbGlobalTypes.Enabled = false;
cbSimpleTypes.SelectedItem = -1;
cbSimpleTypes.Enabled = true;
cbSimpleTypes.SelectedItem = "string";
}
else
{
// an attribute can only be added to a complex type
XmlSchemaComplexType ct = newNode.Parent.Tag as XmlSchemaComplexType;
if (ct != null)
{
// and can reference a global attribute, so enable the global combobox
AddToCollection(ct.Attributes, attrib, newNode, TreeViewImages.Attribute);
cbGlobalTypes.SelectedItem = -1;
cbGlobalTypes.Enabled = true;
cbSimpleTypes.SelectedItem = "string";
cbSimpleTypes.Enabled = true;
}
else
{
newNode.Parent.Nodes.Remove(newNode);
MessageBox.Show("Cannot create an attribute for this item.");
}
}
}
#endregion
#region Add Element
// An element can be added to the schema or to a complex type.
// If adding to an element, convert the element to a complex type.
// An element can be added to a global complex type or to a local complex type.
private void mnuAddElement_Click(object sender, System.EventArgs e)
{
TreeNode newNode = CreateNode("Element");
XmlSchemaElement element = new XmlSchemaElement();
element.Name = "Element";
element.SchemaTypeName = new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema");
// root node?
if (newNode.Parent == tvSchema.Nodes[0])
{
// add to root of schema. A global element can reference another global type
AddToCollection(schema.Items, element, newNode, TreeViewImages.Element);
cbGlobalTypes.Items.Add(new GlobalElementType(element.Name, element));
cbGlobalTypes.Enabled = true;
cbSimpleTypes.SelectedItem = -1;
cbSimpleTypes.Enabled = true;
cbSimpleTypes.SelectedItem = "string";
}
else
{
// otherwise, an element must be part of a complex type
bool ret = AddToComplexType(newNode.Parent.Tag, element, newNode, TreeViewImages.Element);
if (!ret)
{
// not successful
newNode.Parent.Nodes.Remove(newNode);
MessageBox.Show("Cannot add an element to this item.");
}
else
{
// successful
cbGlobalTypes.SelectedItem = -1;
cbGlobalTypes.Enabled = true;
cbSimpleTypes.SelectedItem = "string";
cbSimpleTypes.Enabled = true;
}
}
}
#endregion
#region Add Simple Type
// A simple type can be added as a global type or as a local member of a complex type.
// A simple type cannot contain elements or attributes.
// Simple types are derived from basic types or other simple types.
// The complex type can either be a global definition or a local complex type.
// When adding to a complex type, the simple type must be wrapped in an element.
private void mnuAddSimpleType_Click(object sender, System.EventArgs e)
{
TreeNode newNode = CreateNode("SimpleType");
XmlSchemaSimpleType simpleType = new XmlSchemaSimpleType();
simpleType.Name = "SimpleType";
XmlSchemaSimpleTypeRestriction restriction = new XmlSchemaSimpleTypeRestriction();
restriction.BaseTypeName = new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema");
simpleType.Content = restriction;
// root node?
if (newNode.Parent == tvSchema.Nodes[0])
{
// add to root of schema. A global simple type cannot reference another global
AddToCollection(schema.Items, simpleType, newNode, TreeViewImages.SimpleType);
cbGlobalTypes.Items.Add(new GlobalElementType(simpleType.Name, simpleType));
cbGlobalTypes.Enabled = false;
cbSimpleTypes.SelectedItem = -1;
cbSimpleTypes.Enabled = true;
cbSimpleTypes.SelectedItem = "string";
}
else
{
// if not a root node, then it must be created as an element of simple type...
XmlSchemaElement el = new XmlSchemaElement();
el.Name = "SimpleType";
el.SchemaType = simpleType;
simpleType.Name = null;
// ...as a subnode to a complex type
bool ret = AddToComplexType(newNode.Parent.Tag, el, newNode, TreeViewImages.SimpleType);
if (!ret)
{
// failure
newNode.Parent.Nodes.Remove(newNode);
MessageBox.Show("Cannot add a simple type to this item.");
}
else
{
// success. Can reference a global simple type
cbGlobalTypes.SelectedItem = -1;
cbGlobalTypes.Enabled = true;
cbSimpleTypes.SelectedItem = "string";
cbSimpleTypes.Enabled = true;
}
}
}
#endregion
#region Add Complex Type
// A complex type can be added as a global type to the schema or as a complex element.
// If adding to an element, change the element to a complex type.
// When adding to a complex type, the complex type must be wrapped in an element.
private void mnuAddComplexType_Click(object sender, System.EventArgs e)
{
TreeNode newNode = CreateNode("ComplexType");
XmlSchemaComplexType complexType = new XmlSchemaComplexType();
XmlSchemaSequence sequence = new XmlSchemaSequence();
complexType.Particle = sequence;
complexType.Name = "ComplexType";
// root node?
if (newNode.Parent == tvSchema.Nodes[0])
{
// add to root. A complex type has no type reference information.
AddToCollection(schema.Items, complexType, newNode, TreeViewImages.ComplexType);
cbGlobalTypes.Items.Add(new GlobalElementType(complexType.Name, complexType));
cbSimpleTypes.SelectedItem = -1;
cbGlobalTypes.SelectedItem = -1;
cbSimpleTypes.Enabled = false;
cbGlobalTypes.Enabled = false;
}
else
{
// if not at root, create an element of complex type...
XmlSchemaElement el = new XmlSchemaElement();
el.Name = "ComplexType";
el.SchemaType = complexType;
complexType.Name = null;
// ...that is added as a subnode to a complex type.
bool ret = AddToComplexType(newNode.Parent.Tag, el, newNode, TreeViewImages.ComplexType);
if (!ret)
{
// failure
newNode.Parent.Nodes.Remove(newNode);
MessageBox.Show("Cannot add a complex type to this item.");
}
else
{
// success. No type is referenced.
cbSimpleTypes.SelectedItem = -1;
cbGlobalTypes.SelectedItem = -1;
cbSimpleTypes.Enabled = false;
cbGlobalTypes.Enabled = false;
}
}
}
#endregion
#region New
private void mnuNew_Click(object sender, System.EventArgs e)
{
CreateRootNode(); // create a new treeview root node
schema = new XmlSchema(); // create a new schema
CompileSchema(); // compile and show it
fileName = null; // no filename
}
#endregion
#region Open
// open an existing XSD file
private void mnuOpen_Click(object sender, System.EventArgs e)
{
openSchemaDialog.DefaultExt = "xsd";
openSchemaDialog.CheckFileExists = true;
openSchemaDialog.Filter = "XSD Files (*.xsd)|*.xsd|All Files (*.*)|*.*";
DialogResult res = openSchemaDialog.ShowDialog();
if (res == DialogResult.OK)
{
try
{
StreamReader tr = new StreamReader(openSchemaDialog.FileName);
schema = XmlSchema.Read(tr, new ValidationEventHandler(SchemaValidationHandler));
tr.Close();
CompileSchema();
CreateRootNode();
DecodeSchema(schema, tvSchema.Nodes[0]);
tvSchema.ExpandAll();
fileName = openSchemaDialog.FileName;
}
catch (Exception err)
{
edSchemaErrors.Text = err.ToString();
}
}
}
#endregion
#region Save, Save As, Exit, About
// save the current XSD
private void mnuSave_Click(object sender, System.EventArgs e)
{
if (fileName == null)
{
mnuSaveAs_Click(sender, e);
}
else
{
CompileSchema();
StreamWriter sw = new StreamWriter(fileName, false, System.Text.Encoding.UTF8);
sw.Write(edSchema.Text);
sw.Flush();
sw.Close();
}
}
// save the current XSD as...
private void mnuSaveAs_Click(object sender, System.EventArgs e)
{
DialogResult res = saveAsSchemaDialog.ShowDialog();
if (res == DialogResult.OK)
{
fileName = saveAsSchemaDialog.FileName;
CompileSchema();
StreamWriter sw = new StreamWriter(fileName, false, System.Text.Encoding.UTF8);
sw.Write(edSchema.Text);
sw.Flush();
sw.Close();
}
}
private void mnuExit_Click(object sender, System.EventArgs e)
{
Close(); // signal form to close
}
// info
private void mnuAbout_Click(object sender, System.EventArgs e)
{
MessageBox.Show("XML Schema Editor\r\n\r\nversion 1.0\r\n\r\n(c)2003 Marc Clifton\r\n\r\nThis program may be freely distributed.");
}
#endregion
#region Compile
private void mnuCompile_Click(object sender, System.EventArgs e)
{
// 1. read the XSD from the edit box into a schema
// 2. compile it
// 3. create a new tree view
// 4. decode the schema into the tree view
// 5. show the tree
try
{
StringReader sr = new StringReader(edSchema.Text);
schema = XmlSchema.Read(sr, new ValidationEventHandler(SchemaValidationHandler));
CompileSchema();
CreateRootNode();
DecodeSchema(schema, tvSchema.Nodes[0]);
tvSchema.ExpandAll();
}
catch (Exception err)
{
edSchemaErrors.Text = err.ToString();
}
}
#endregion
#region Remove Node
// The parent type determines from what list the selected item must be removed.
// Use the image index in the tree view to figure out the parent type.
private void mnuRemoveNode_Click(object sender, System.EventArgs e)
{
TreeNode tnParent = tvSchema.SelectedNode.Parent;
XmlSchemaObject obj = tvSchema.SelectedNode.Tag as XmlSchemaObject;
bool success = false;
// if the node to remove has a parent and is of an XmlSchemaObject type...
if ((tnParent != null) && (obj != null))
{
// look at the tree node image index to figure out what the parent is!
switch ((TreeViewImages)tnParent.ImageIndex)
{
// if the parent is the schema root:
case TreeViewImages.Schema:
{
// remove the object from the schema and from the global list
schema.Items.Remove(obj);
int idx = cbGlobalTypes.FindStringExact(tvSchema.SelectedNode.Text);
if (idx != -1)
{
cbGlobalTypes.Items.RemoveAt(idx);
}
success = true;
break;
}
// if the parent is an annotation type
case TreeViewImages.Annotation:
{
XmlSchemaAnnotation annot = tnParent.Tag as XmlSchemaAnnotation;
if (annot != null)
{
annot.Items.Remove(obj);
success = true;
}
break;
}
// if the parent is a simple type
case TreeViewImages.SimpleType:
{
// a simple type can have an annotation or a facet type as children
XmlSchemaSimpleType st = tnParent.Tag as XmlSchemaSimpleType;
if (obj is XmlSchemaAnnotation)
{
// remove from annotation list if it's an annotation type
st.Annotation.Items.Remove(obj);
success = true;
}
else if (obj is XmlSchemaFacet)
{
XmlSchemaSimpleTypeRestriction rest = st.Content as XmlSchemaSimpleTypeRestriction;
if (rest != null)
{
// remove from facet list if it's a facet type
rest.Facets.Remove(obj);
success = true;
}
}
break;
}
// if the parent is a complex type...
case TreeViewImages.ComplexType:
{
XmlSchemaComplexType ct = tnParent.Tag as XmlSchemaComplexType;
if (ct != null)
{
// then we are removing an attribute
if (obj is XmlSchemaAttribute)
{
ct.Attributes.Remove(obj);
success = true;
}
// or an annotation
else if (obj is XmlSchemaAnnotation)
{
ct.Annotation.Items.Remove(obj);
success = true;
}
// or an element type
else
{
XmlSchemaSequence seq = ct.Particle as XmlSchemaSequence;
if (seq != null)
{
seq.Items.Remove(obj);
success = true;
}
}
}
break;
}
}
}
// if successful, remove the node from the tree view
if (success)
{
tnParent.Nodes.Remove(tvSchema.SelectedNode);
CompileSchema();
}
else
{
MessageBox.Show("Unable to remove this node");
}
}
#endregion
#endregion
#region Schema Validation Handler
// report any errors to the schema error edit box
private void SchemaValidationHandler(object sender, ValidationEventArgs args)
{
Console.WriteLine(args.Message);
edSchemaErrors.Text += args.Message + "\r\n";
}
#endregion
#region Events
#region TreeView PreEventLabelChanged and EventLabelChanged
// exclude certain tree nodes from being editable
private void PreEventLabelChanged(object sender, NodeLabelEditEventArgs e)
{
prevLabel = tvSchema.SelectedNode.Text;
if ((e.Node.Tag is XmlSchemaFacet) ||
(e.Node.Tag is XmlSchemaAnnotation) ||
(e.Node.Tag is XmlSchemaDocumentation) ||
(e.Node.Tag is XmlSchemaAppInfo))
{
e.Node.EndEdit(false);
}
}
private void EventLabelChanged(object sender, NodeLabelEditEventArgs e)
{
// if a node is selected...
if (e.Node != null)
{
// and a label has been changed... (e.Label==null if ESC key pressed)
if (e.Label != null)
{
// then change the name of the type in the schema
UpdateTypeAndName(null, e.Label, null);
// if this is a root node...
if (e.Node.Parent == tvSchema.Nodes[0])
{
// ...then also change the name in the global list
// (this is not case sensitive!)
int idx = cbGlobalTypes.FindStringExact(prevLabel);
if (idx != -1)
{
cbGlobalTypes.Items[idx] = new GlobalElementType(e.Label, ((GlobalElementType)cbGlobalTypes.Items[idx]).type);
}
}
}
}
}
#endregion
#region EventTreeViewKeyPress
// shortcuts:
// F2 - edit tree node label
// Ctrl+A - bring up popup menu to Add a subnode
// Ctrl+T - go to Top of tree
// Ctrl+P - go to Parent of currently selected node
private void EventTreeViewKeyUp(object sender, KeyEventArgs e)
{
e.Handled = false;
// F2
if (e.KeyCode == Keys.F2)
{
if (tvSchema.SelectedNode != tvSchema.Nodes[0])
{
tvSchema.SelectedNode.BeginEdit();
e.Handled = true;
}
}
// Ctrl+A
else if ((e.KeyCode == Keys.A) && (e.Modifiers == Keys.Control))
{
e.Handled = true;
tvcmSchema.Show(this, tvSchema.Location + new Size(50, 50));
}
// Ctrl+T
else if ((e.KeyCode == Keys.T) && (e.Modifiers == Keys.Control))
{
e.Handled = true;
tvSchema.SelectedNode = tvSchema.Nodes[0];
}
// Ctrl+P
else if ((e.KeyCode == Keys.P) && (e.Modifiers == Keys.Control))
{
e.Handled = true;
TreeNode node = tvSchema.SelectedNode.Parent;
if (node != null)
{
tvSchema.SelectedNode = node;
}
}
}
#endregion
#region Schema Text Box Lost Focus
private void EventSchemaTextBoxLostFocus(object sender, EventArgs e)
{
mnuCompile_Click(sender, e);
}
#endregion
#region TreeView MouseDown
// On a mouse down, we want to select the node on which the mouse clicked.
// This way we know what node the user right-clicked on when adding sub-nodes
private void EventMouseDown(object sender, MouseEventArgs e)
{
TreeNode tn = tvSchema.GetNodeAt(e.X, e.Y);
if (tn != null)
{
tvSchema.SelectedNode = tn;
}
}
#endregion
#region TreeView AfterSelect
// After selecting a node, we want to:
// 1. highlight the line in the schema that corresponds to the tree node
// 2. update the simple and global type combo boxes to show what the type is for the selected node.
private void tvSchema_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
{
XmlSchemaObject obj = e.Node.Tag as XmlSchemaObject;
// if this is a schema object...
if (obj != null)
{
// find the corresponding line in the XSD source and highlight it
if ((obj.LineNumber != 0) && (obj.LineNumber < edSchema.Lines.Length))
{
int length = 0;
for (int i = 0; i < obj.LineNumber - 1; i++)
{
// get the length of the line including CRLF
length += edSchema.Lines[i].Length + 2;
}
// highlight the line
edSchema.Select(length, edSchema.Lines[obj.LineNumber - 1].Length);
}
// Update simple and global type combo boxes.
// Get the name of the element type so that we can find it in the simple or global type list
XmlQualifiedName name = null; // assume failure
if (obj is XmlSchemaAttribute)
{
// this is easy.
name = ((XmlSchemaAttribute)obj).SchemaTypeName;
}
else if (obj is XmlSchemaSimpleType)
{
// if it's a simple type, get the restriction type, if it exists
XmlSchemaSimpleTypeRestriction restriction = ((XmlSchemaSimpleType)obj).Content as XmlSchemaSimpleTypeRestriction;
if (restriction != null)
{
name = restriction.BaseTypeName;
}
}
else if (obj is XmlSchemaElement)
{
// if it's an element, determine if it's a simple type subnode of a complex type...
// and then get the restriction type, if it exists
XmlSchemaElement el = obj as XmlSchemaElement;
if (el.SchemaType is XmlSchemaSimpleType)
{
XmlSchemaSimpleType st = el.SchemaType as XmlSchemaSimpleType;
XmlSchemaSimpleTypeRestriction rest = st.Content as XmlSchemaSimpleTypeRestriction;
if (rest != null)
{
name = rest.BaseTypeName;
}
}
else
{
// otherwise get the element name
name = el.SchemaTypeName;
// if the name is null, then there must be a reference instead
if (name.Name == "")
{
name = el.RefName;
}
}
}
// select the name from either the simple type list or the global element type list
if (name != null)
{
// see if the name exists in the simple type list
int idx = cbSimpleTypes.FindStringExact(name.Name);
cbSimpleTypes.SelectedIndex = idx;
cbSimpleTypes.Enabled = true;
// see if the name exists in the complex type list
idx = cbGlobalTypes.FindStringExact(name.Name);
cbGlobalTypes.SelectedIndex = idx;
cbGlobalTypes.Enabled = true;
}
else
{
// if there is no name, then disable the comboboxes
cbSimpleTypes.SelectedIndex = -1;
cbGlobalTypes.SelectedIndex = -1;
cbSimpleTypes.Enabled = false;
cbGlobalTypes.Enabled = false;
}
}
else
{
// if this isn't a schema object, then disable the comboboxes
cbSimpleTypes.SelectedIndex = -1;
cbGlobalTypes.SelectedIndex = -1;
cbSimpleTypes.Enabled = false;
cbGlobalTypes.Enabled = false;
}
}
#endregion
#region cbSimpleTypes Index Changed
// the user has selected a simple type. Select it and clear the global type combo box.
private void cbSimpleTypes_SelectedIndexChanged(object sender, System.EventArgs e)
{
if (cbSimpleTypes.SelectedIndex != -1)
{
UpdateTypeAndName(cbSimpleTypes.SelectedItem.ToString(), null, "http://www.w3.org/2001/XMLSchema");
cbGlobalTypes.SelectedIndex = -1;
}
}
#endregion
#region cbGlobalTypes Index Changed
// the user has selected a global type. Select it and clear the simple type combo box.
private void cbGlobalTypes_SelectedIndexChanged(object sender, System.EventArgs e)
{
if (cbGlobalTypes.SelectedIndex != -1)
{
UpdateTypeAndName(cbGlobalTypes.SelectedItem.ToString(), null, null);
cbSimpleTypes.SelectedIndex = -1;
}
}
#endregion
#endregion
#region Misc. Helpers
#region CreateRootNode
// This helper function destroys the existing tree and creates a new tree.
// It also clears the global type list, since there are no global types defined
// with a blank tree.
private void CreateRootNode()
{
tvSchema.Nodes.Clear();
TreeNode rootNode = new TreeNode("Schema:");
tvSchema.Nodes.Add(rootNode);
rootNode.ImageIndex = (int)TreeViewImages.Schema;
rootNode.SelectedImageIndex = (int)TreeViewImages.Schema;
cbGlobalTypes.Items.Clear();
}
#endregion
#region CompileSchema
// Compile the schema as it exists in the XmlSchema structure, displaying any
// errors in the schema error edit box and displaying the schema itself in
// the schema edit box.
private void CompileSchema()
{
edSchemaErrors.Text = "";
schema.Compile(new ValidationEventHandler(SchemaValidationHandler));
StringWriter sw = new StringWriter();
schema.Write(sw);
edSchema.Text = sw.ToString();
}
#endregion
#region CreateNode
// This helper function creates a subnode off of the selected node and requests
// that the node label be immediately editable.
private TreeNode CreateNode(string name)
{
TreeNode tn = tvSchema.SelectedNode;
TreeNode newNode = new TreeNode(name);
tn.Nodes.Add(newNode);
tn.Expand();
tvSchema.SelectedNode = newNode;
newNode.BeginEdit();
return newNode;
}
#endregion
#region AddToCollection
// Add a schema type to the specified schema object collection.
// The tree node references the schema type being added.
// The image indices are set.
// The schema is recompiled, which shows any errors and updates the schema display.
void AddToCollection(XmlSchemaObjectCollection coll, XmlSchemaObject obj, TreeNode node, TreeViewImages imgIdx)
{
coll.Add(obj);
node.Tag = obj;
node.ImageIndex = (int)imgIdx;
node.SelectedImageIndex = (int)imgIdx;
CompileSchema();
}
#endregion
#region ChangeElementToComplexType
// When adding a subnode to an element or a simple type, the node must be changed to a complex type.
private XmlSchemaComplexType ChangeElementToComplexType(XmlSchemaElement el, TreeNode tn)
{
// if the element is currently a reference, we need to remove the reference
// and set the name to something, which in this case is the old ref name.
if (el.RefName != null)
{
el.Name = el.RefName.Name;
el.RefName = null;
}
// creat the complex type.
XmlSchemaComplexType ct = new XmlSchemaComplexType();
el.SchemaType = ct;
// a complex type cannot have a type name
el.SchemaTypeName = null;
// create the sequence
XmlSchemaSequence sequence = new XmlSchemaSequence();
ct.Particle = sequence;
// update the image indices
tn.ImageIndex = (int)TreeViewImages.ComplexType;
tn.SelectedImageIndex = (int)TreeViewImages.ComplexType;
return ct;
}
#endregion
#region AddToComplexType
// add a type to a complex type
private bool AddToComplexType(object obj, XmlSchemaObject item, TreeNode newNode, TreeViewImages imgIdx)
{
bool success = true;
XmlSchemaElement el = obj as XmlSchemaElement;
XmlSchemaComplexType complexType = obj as XmlSchemaComplexType;
// is it an element...
if (el != null)
{
// of complex type (so we know it's a local complex type, not a global one!)
XmlSchemaComplexType ct = el.SchemaType as XmlSchemaComplexType;
if (ct != null)
{
// does it have a sequence?
XmlSchemaSequence seq = ct.Particle as XmlSchemaSequence;
if (seq != null)
{
// yes--add it to the sequence collection
AddToCollection(seq.Items, item, newNode, imgIdx);
}
else
{
// no--we can't add it.
MessageBox.Show("Complex type is missing sequence!");
success = false;
}
}
else
{
// change the basic element to a complex type by adding a sequence and then
// add the sub-element
ct = ChangeElementToComplexType(el, newNode.Parent);
AddToCollection(((XmlSchemaSequence)ct.Particle).Items, item, newNode, imgIdx);
}
}
// or is it a global complex type...
else if (complexType != null)
{
XmlSchemaSequence seq = complexType.Particle as XmlSchemaSequence;
// which should have a sequence!
if (seq != null)
{
// yes--add it to the collection
AddToCollection(seq.Items, item, newNode, imgIdx);
}
else
{
// no--we can't add it.
MessageBox.Show("Complex type is missing sequence!");
success = false;
}
}
else
{
// failure--current node is not an element and not a complex type
success = false;
}
return success;
}
#endregion
#region UpdateTypeAndName
// This is a dual purpose function that updates either the type or the name.
// It can also update both at once, but isn't used in that way in this program.
// Pass in a null for typeName if only changing the name.
// Pass in a null for name if only changing the typeName.
// Pass in a null for the nameSpace if the typeName is a global type.
private void UpdateTypeAndName(string typeName, string name, string nameSpace)
{
// Is the type referenced by the tree node an XmlSchemaObject?
XmlSchemaObject obj = tvSchema.SelectedNode.Tag as XmlSchemaObject;
if (obj != null)
{
// is it an attribute?
if (obj is XmlSchemaAttribute)
{
XmlSchemaAttribute attrib = obj as XmlSchemaAttribute;
// if we're changing the name:
if (name != null)
{
attrib.Name = name;
CompileSchema();
}
// if we're changing the type:
if (typeName != null)
{
// if the name refers to a global attribute, then use ref instead of type
int idx = cbGlobalTypes.FindStringExact(typeName);
GlobalElementType glet = null;
if (idx != -1)
{
glet = cbGlobalTypes.Items[idx] as GlobalElementType;
}
// if a global exists of this type...
if ((glet != null) && (glet.type is XmlSchemaAttribute))
{
// then get rid of the type name and use a ref instead
attrib.SchemaTypeName = null;
attrib.RefName = new XmlQualifiedName(typeName, nameSpace);
// can't have a name
attrib.Name = null;
}
else
{
// otherwise, use a type name and get rid of the ref
attrib.SchemaTypeName = new XmlQualifiedName(typeName, nameSpace);
attrib.RefName = null;
if (attrib.Name == null)
{
// if changing from ref to type, we need some sort of default name
attrib.Name = tvSchema.SelectedNode.Text;
}
}
CompileSchema();
// update the tree node name
tvSchema.SelectedNode.Text = attrib.QualifiedName.Name;
}
}
// is it an element?
else if (obj is XmlSchemaElement)
{
XmlSchemaElement el = obj as XmlSchemaElement;
// if we're changing the name:
if (name != null)
{
el.Name = name;
CompileSchema();
}
// if we're changing the type:
if (typeName != null)
{
if (el.SchemaType is XmlSchemaSimpleType)
{
XmlSchemaSimpleType st = el.SchemaType as XmlSchemaSimpleType;
XmlSchemaSimpleTypeRestriction rest = st.Content as XmlSchemaSimpleTypeRestriction;
if (rest != null)
{
rest.BaseTypeName = new XmlQualifiedName(typeName, nameSpace);
CompileSchema();
}
}
else
{
// if the name refers to a global element, then use ref instead of type
// Same deal as for changing the element type name.
// Since the SchemaTypeName and RefName are not part of any base class shared
// between the SchemaXmlAttribute and SchemaXmlElement, we need separate code.
int idx = cbGlobalTypes.FindStringExact(typeName);
GlobalElementType glet = null;
if (idx != -1)
{
glet = cbGlobalTypes.Items[idx] as GlobalElementType;
}
if ((glet != null) && (glet.type is XmlSchemaElement))
{
el.SchemaTypeName = null;
el.RefName = new XmlQualifiedName(typeName, nameSpace);
el.Name = null;
}
else
{
el.SchemaTypeName = new XmlQualifiedName(typeName, nameSpace);
el.RefName = null;
if (el.Name == null)
{
el.Name = tvSchema.SelectedNode.Text;
}
}
CompileSchema();
tvSchema.SelectedNode.Text = el.QualifiedName.Name;
}
}
}
// is it a simple type?
else if (obj is XmlSchemaSimpleType)
{
XmlSchemaSimpleType st = obj as XmlSchemaSimpleType;
// if we're changing the name:
if (name != null)
{
st.Name = name;
CompileSchema();
}
// if we're changing the type name:
if (typeName != null)
{
// this must be done in the Restriction object
XmlSchemaSimpleTypeRestriction restriction = st.Content as XmlSchemaSimpleTypeRestriction;
if (restriction != null)
{
restriction.BaseTypeName = new XmlQualifiedName(typeName, nameSpace);
CompileSchema();
cbGlobalTypes.SelectedIndex = -1;
}
}
}
// is it a complex type?
else if (obj is XmlSchemaComplexType)
{
// if we're changing the name:
if (name != null)
{
((XmlSchemaComplexType)obj).Name = name;
CompileSchema();
}
// there is no such thing as changing the type of a complex type
}
}
}
#endregion
#region Add Facet
// Add a facet to a simple type.
bool AddFacet(XmlSchemaFacet facet, string val, TreeViewImages imgIdx)
{
// get the simple type.
XmlSchemaSimpleType st = tvSchema.SelectedNode.Tag as XmlSchemaSimpleType;
// assume failure
XmlSchemaSimpleTypeRestriction rs = null;
bool success = false;
// if the simple type exists, get the restriction type
if (st != null)
{
rs = st.Content as XmlSchemaSimpleTypeRestriction;
}
// if the restriction type exists...
if (rs != null)
{
// create the node and add it to the facet collection
TreeNode newNode = CreateNode(facet.ToString());
facet.Value = val;
rs.Facets.Add(facet);
CompileSchema();
success = true;
}
return success;
}
#endregion
#region TextToNodeArray
// a helper to create some default documentation text.
public static XmlNode[] TextToNodeArray(string text)
{
XmlDocument doc = new XmlDocument();
return new XmlNode[1] { doc.CreateTextNode(text) };
}
#endregion
#endregion
#region DecodeSchema
// stub that wraps the actual decoding in a try block so we can display errors
private void DecodeSchema(XmlSchema schema, TreeNode node)
{
try
{
DecodeSchema2(schema, node);
}
catch (Exception err)
{
edSchemaErrors.Text = err.ToString();
}
}
// recursive decoder
private TreeNode DecodeSchema2(XmlSchemaObject obj, TreeNode node)
{
TreeNode newNode = node;
// convert the object to all types and then check what type actually exists
XmlSchemaAnnotation annot = obj as XmlSchemaAnnotation;
XmlSchemaAttribute attrib = obj as XmlSchemaAttribute;
XmlSchemaFacet facet = obj as XmlSchemaFacet;
XmlSchemaDocumentation doc = obj as XmlSchemaDocumentation;
XmlSchemaAppInfo appInfo = obj as XmlSchemaAppInfo;
XmlSchemaElement element = obj as XmlSchemaElement;
XmlSchemaSimpleType simpleType = obj as XmlSchemaSimpleType;
XmlSchemaComplexType complexType = obj as XmlSchemaComplexType;
// If the current node is the root node of the tree, then we are
// possibly adding a global attribute, element, simple type, or complex type.
if (node == tvSchema.Nodes[0])
{
if (attrib != null)
{
if (attrib.Name != null)
{
// add to global list
cbGlobalTypes.Items.Add(new GlobalElementType(attrib.Name, attrib));
}
}
else if (element != null)
{
if (element.Name != null)
{
// add to global list
cbGlobalTypes.Items.Add(new GlobalElementType(element.Name, element));
}
}
else if (simpleType != null)
{
if (simpleType.Name != null)
{
// add to global list
cbGlobalTypes.Items.Add(new GlobalElementType(simpleType.Name, simpleType));
}
}
else if (complexType != null)
{
if (complexType.Name != null)
{
// add to global list
cbGlobalTypes.Items.Add(new GlobalElementType(complexType.Name, complexType));
}
}
}
// if annotation, add a tree node and recurse for documentation and app info
if (annot != null)
{
newNode = new TreeNode("--annotation--");
newNode.Tag = annot;
newNode.ImageIndex = 4;
newNode.SelectedImageIndex = 4;
node.Nodes.Add(newNode);
foreach (XmlSchemaObject schemaObject in annot.Items)
{
DecodeSchema2(schemaObject, newNode);
}
}
else
// if attribute, add a tree node
if (attrib != null)
{
newNode = new TreeNode(attrib.QualifiedName.Name);
newNode.Tag = attrib;
newNode.ImageIndex = 7;
newNode.SelectedImageIndex = 7;
node.Nodes.Add(newNode);
}
else
// if facet, add a tree node
if (facet != null)
{
newNode = new TreeNode(facet.ToString());
newNode.Tag = facet;
newNode.ImageIndex = 8;
newNode.SelectedImageIndex = 8;
node.Nodes.Add(newNode);
}
else
// if documentation, add a tree node
if (doc != null)
{
newNode = new TreeNode("--documentation--");
newNode.Tag = doc;
newNode.ImageIndex = 5;
newNode.SelectedImageIndex = 5;
node.Nodes.Add(newNode);
}
else
// if app info, add a tree node
if (appInfo != null)
{
newNode = new TreeNode("--app info--");
newNode.Tag = annot;
newNode.ImageIndex = 6;
newNode.SelectedImageIndex = 6;
node.Nodes.Add(newNode);
}
else
// if an element, determine whether the element is a simple type or a complex type
if (element != null)
{
XmlSchemaSimpleType st = element.SchemaType as XmlSchemaSimpleType;
XmlSchemaComplexType ct = element.SchemaType as XmlSchemaComplexType;
if (st != null)
{
// this is a simple type element. Recurse.
TreeNode node2 = DecodeSchema2(st, newNode);
node2.Text = element.Name;
}
else if (ct != null)
{
// this is a complex type element. Recurse.
TreeNode node2 = DecodeSchema2(ct, newNode);
node2.Text = element.Name;
}
else
{
// This is a plain ol' fashioned element.
newNode = new TreeNode(element.QualifiedName.Name);
newNode.Tag = element;
newNode.ImageIndex = 1;
newNode.SelectedImageIndex = 1;
node.Nodes.Add(newNode);
}
}
else
// if a simple type, then add a tree node and recurse facets
if (simpleType != null)
{
newNode = new TreeNode(simpleType.QualifiedName.Name);
newNode.Tag = simpleType;
newNode.ImageIndex = 2;
newNode.SelectedImageIndex = 2;
node.Nodes.Add(newNode);
XmlSchemaSimpleTypeRestriction rest = simpleType.Content as XmlSchemaSimpleTypeRestriction;
if (rest != null)
{
foreach (XmlSchemaFacet schemaObject in rest.Facets)
{
DecodeSchema2(schemaObject, newNode);
}
}
}
else
// if a complex type, add a tree node and recurse its sequence
if (complexType != null)
{
newNode = new TreeNode(complexType.Name);
newNode.Tag = complexType;
newNode.ImageIndex = 3;
newNode.SelectedImageIndex = 3;
node.Nodes.Add(newNode);
XmlSchemaSequence seq = complexType.Particle as XmlSchemaSequence;
if (seq != null)
{
foreach (XmlSchemaObject schemaObject in seq.Items)
{
DecodeSchema2(schemaObject, newNode);
}
}
}
// now recurse any object collection of the type.
foreach (PropertyInfo property in obj.GetType().GetProperties())
{
if (property.PropertyType.FullName == "System.Xml.Schema.XmlSchemaObjectCollection")
{
XmlSchemaObjectCollection childObjectCollection = (XmlSchemaObjectCollection)property.GetValue(obj, null);
foreach (XmlSchemaObject schemaObject in childObjectCollection)
{
DecodeSchema2(schemaObject, newNode);
}
}
}
return newNode;
}
#endregion
private void Process()
{
try
{
if (fileName == null)
return;
StreamReader tr = new StreamReader(fileName);
schema = XmlSchema.Read(tr, new ValidationEventHandler(SchemaValidationHandler));
tr.Close();
CompileSchema();
CreateRootNode();
DecodeSchema(schema, tvSchema.Nodes[0]);
tvSchema.ExpandAll();
if (outputFileName == null)
return;
GenerateCode();
Application.Exit();
}
catch (Exception err)
{
edSchemaErrors.Text = err.ToString();
}
}
private void menuItem8_Click(object sender, System.EventArgs e)
{
try
{
if (fileName == null)
{
MessageBox.Show("You need to load an XML Schema first before you can generate code.", "Cannot generate code");
return;
}
openSchemaDialog.DefaultExt = "cs";
openSchemaDialog.CheckFileExists = false;
openSchemaDialog.FileName = "AppConfig";
openSchemaDialog.Filter = "CS Files (*.cs)|*.cs|All Files (*.*)|*.*";
DialogResult res = openSchemaDialog.ShowDialog();
if (res == DialogResult.OK)
{
outputFileName = openSchemaDialog.FileName;
GenerateCode();
}
}
catch (Exception err)
{
throw err;
}
}
private void GenerateCode()
{
if (outputNamespace == null)
menuItem10_Click(null, null);
if ((outputNamespace == null) || (outputNamespace.Length <= 0))
{
MessageBox.Show("You must provide a namespace in order to generate the configuration class", "Namespace");
return;
}
// init variables
sbOutput.Length = 0;
sbField.Length = 0;
sbProperty.Length = 0;
sbLoadValue.Length = 0;
flagTopElement = true;
// add reference
targetUnit = new CodeCompileUnit();
CodeNamespace targetNamespace = new CodeNamespace(outputNamespace);
targetNamespace.Imports.AddRange(new CodeNamespaceImport[] {
new CodeNamespaceImport("System"),
new CodeNamespaceImport("System.Collections"),
new CodeNamespaceImport("System.Configuration"),
new CodeNamespaceImport("System.Xml"),
new CodeNamespaceImport("System.IO"),
new CodeNamespaceImport("System.Web")
});
// add AppConfigHandler class
CodeTypeDeclaration targetClass = new CodeTypeDeclaration("AppConfigHandler");
targetClass.IsClass = true;
targetClass.TypeAttributes = TypeAttributes.NotPublic;
targetClass.BaseTypes.Add(new CodeTypeReference("IConfigurationSectionHandler"));
// add Create method to AppConfigHandler class
CodeMemberMethod targetMethod = new CodeMemberMethod();
targetMethod.Name = "Create";
targetMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
targetMethod.ReturnType = new CodeTypeReference(typeof(object));
targetMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "parent"));
targetMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "context"));
targetMethod.Parameters.Add(new CodeParameterDeclarationExpression("XmlNode", "node"));
// add statement to Create method
targetMethod.Statements.Add(new CodeSnippetStatement(@"
try
{
AppConfig _config = new AppConfig();
_config.LoadValues(node);
return _config;
}
catch(Exception ex)
{
throw ex;
}
"));
targetClass.Members.Add(targetMethod);
targetNamespace.Types.Add(targetClass);
// create AppConfig class
targetClass = new CodeTypeDeclaration("AppConfig");
targetClass.IsClass = true;
targetClass.TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed;
// create LoadAppValues method
loadAppValuesMethod = new CodeMemberMethod();
loadAppValuesMethod.Name = "LoadAppValues";
loadAppValuesMethod.Attributes = MemberAttributes.Family | MemberAttributes.Final;
loadAppValuesMethod.ReturnType = new CodeTypeReference();
loadAppValuesMethod.Parameters.Add(new CodeParameterDeclarationExpression("XmlNode", "currentConfigNode"));
// add statement to LoadAppValues method
//loadAppValuesMethod.Statements.Add(new CodeCommentStatement("Test comment statement"));
loadAppValuesMethod.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("XmlNode"), "node"));
loadAppValuesMethod.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("XmlNodeList"), "nodeList"));
// prepare AppConfig class from Schema
OutputSchema(schema, targetClass);
// create LoadValues method
targetMethod = new CodeMemberMethod();
targetMethod.Name = "LoadValues";
targetMethod.Attributes = MemberAttributes.Assembly | MemberAttributes.Final;
targetMethod.ReturnType = new CodeTypeReference();
targetMethod.Parameters.Add(new CodeParameterDeclarationExpression("XmlNode", "node"));
// add statement to LoadValues method
targetMethod.Statements.Add(new CodeSnippetStatement(@"
XmlNode currentConfigNode = null;
try
{
XmlNode appEnvironmentNode = node.SelectSingleNode(""AppEnvironment"");
if (appEnvironmentNode != null)
{
XmlAttribute att = appEnvironmentNode.Attributes[""configSource""];
if (att == null)
throw new Exception(""configSource attribute missed."");
if ((att.Value == null) || (att.Value.Trim().Length == 0))
throw new Exception(""configSource attribute value missed"");
string environmentConfig = att.Value;
// to get the path for the executable file that started the application, without the executable name
string appPath = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
string xmlFileName = Path.Combine(appPath, environmentConfig);
if (File.Exists(xmlFileName))
{
XmlDocument doc = new XmlDocument();
doc.Load(xmlFileName);
if (doc.HasChildNodes)
{
XmlNode childNode = doc.SelectSingleNode(""AppConfigSettings"");
if (childNode != null)
{
LoadAppValues(childNode);
}
}
else
{
throw new Exception(""Bad file format in config source file: "" + xmlFileName);
}
}
else
{
throw new Exception(""Cannot find sustom config file: "" + xmlFileName);
}
}
else
throw new Exception(""AppEnvironment must be specified."");
}
catch (Exception ex)
{
throw new Exception(""Configuration error in AppConfig section: "" + ex.Message);
}
"));
targetClass.Members.Add(targetMethod);
targetClass.Members.Add(loadAppValuesMethod);
targetNamespace.Types.Add(targetClass);
targetUnit.Namespaces.Add(targetNamespace);
string sOut = sbOutput.ToString();
GenerateCSharpCode(outputFileName);
}
#region OutputSchema
// recursive decoder
CodeExpression[] ceRef = new CodeExpression[1];
private void OutputSchema(XmlSchemaObject obj, CodeTypeDeclaration tClass)
{ OutputSchema(obj, tClass, null, null, ref ceRef, null); }
private void OutputSchema(XmlSchemaObject obj, CodeTypeDeclaration tClass, CodeConstructor tConstructor)
{ OutputSchema(obj, tClass, tConstructor, null, ref ceRef, null); }
private void OutputSchema(XmlSchemaObject obj, CodeTypeDeclaration tClass, CodeConstructor tConstructor, CodeTypeDeclaration tParentClass, ref CodeExpression[] tParameter, CodeStatementCollection tDeclaration)
{
// convert the object to all types and then check what type actually exists
XmlSchemaAnnotation annot = obj as XmlSchemaAnnotation;
XmlSchemaAttribute attrib = obj as XmlSchemaAttribute;
XmlSchemaFacet facet = obj as XmlSchemaFacet;
XmlSchemaDocumentation doc = obj as XmlSchemaDocumentation;
XmlSchemaAppInfo appInfo = obj as XmlSchemaAppInfo;
XmlSchemaElement element = obj as XmlSchemaElement;
XmlSchemaSimpleType simpleType = obj as XmlSchemaSimpleType;
XmlSchemaComplexType complexType = obj as XmlSchemaComplexType;
// if annotation, add a tree node and recurse for documentation and app info
if (annot != null)
{
foreach (XmlSchemaObject schemaObject in annot.Items)
{
OutputSchema(schemaObject, tClass);
}
}
else
// if attribute, add a tree node
if (attrib != null)
{
string s = attrib.QualifiedName.Name;
}
else
// if facet, add a tree node
if (facet != null)
{
string s = facet.ToString();
}
else
// if documentation, add a tree node
if (doc != null)
{
string s = doc.ToString();
}
else
// if app info, add a tree node
if (appInfo != null)
{
string s = annot.ToString();
}
else
// if an element, determine whether the element is a simple type or a complex type
if (element != null)
{
CodeExpression[] ceP = null;
CodeStatementCollection csD = null;
XmlSchemaSimpleType st = element.SchemaType as XmlSchemaSimpleType;
XmlSchemaComplexType ct = element.SchemaType as XmlSchemaComplexType;
System.Type cmType = null;
string cmTypeString = string.Empty;
if (st != null)
{
// this is a simple type element. Recurse.
sbOutput.Append("\r\nSimple Element: " + element.Name);
OutputSchema(st, tClass);
}
#region else if (ct != null)
else if (ct != null)
{
// this is a complex type element. Recurse.
// Declare the field.
CodeMemberField cmField = new CodeMemberField();
cmField.Attributes = MemberAttributes.Private;
cmField.Name = "fld" + element.QualifiedName.Name;
cmField.Type = new CodeTypeReference(element.QualifiedName.Name);
if (tConstructor != null)
{
// constructor
tConstructor.Parameters.Add(new CodeParameterDeclarationExpression(cmField.Type, "_" + cmField.Name));
tConstructor.Statements.Add(
new CodeAssignStatement(new CodeVariableReferenceExpression(cmField.Name),
new CodeVariableReferenceExpression("_" + cmField.Name)));
}
CodeTypeDeclaration collectionClass = null;
CodeTypeDeclaration subClass;
subClass = new CodeTypeDeclaration(element.QualifiedName.Name);
subClass.IsClass = true;
subClass.TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed;
#region if (element.MaxOccurs > 1)
if (element.MaxOccurs > 1)
{
CodeMemberField cmCollectionField = new CodeMemberField();
cmCollectionField.Attributes = MemberAttributes.Private;
cmCollectionField.Name = "fld" + element.QualifiedName.Name + "Collection";
// private ProvinceCollection provinces = new ProvinceCollection();
cmCollectionField.Type = new CodeTypeReference(element.QualifiedName.Name + "Collection");
cmCollectionField.InitExpression =
new CodeObjectCreateExpression(
new CodeTypeReference(element.QualifiedName.Name + "Collection"));
tClass.Members.Add(cmCollectionField);
collectionClass = new CodeTypeDeclaration(element.QualifiedName.Name + "Collection");
collectionClass.IsClass = true;
collectionClass.TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed;
collectionClass.BaseTypes.Add(new CodeTypeReference("CollectionBase"));
collectionClass.Members.Add(subClass);
tClass.Members.Add(collectionClass);
CodeMemberMethod tMethod = new CodeMemberMethod();
tMethod.Name = "Add";
tMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
tMethod.Parameters.Add(new CodeParameterDeclarationExpression(cmField.Type, "_" + element.QualifiedName.Name));
// add statement to Create method
tMethod.Statements.Add(new CodeSnippetStatement("this.List.Add(" + "_" + element.QualifiedName.Name + ");"));
collectionClass.Members.Add(tMethod);
CodeMemberProperty cmProperty = new CodeMemberProperty();
cmProperty.Name = "Item";
cmProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final;
cmProperty.Type = new CodeTypeReference(subClass.Name);
cmProperty.Parameters.Add(new CodeParameterDeclarationExpression(
new CodeTypeReference(typeof(int)), "index"));
cmProperty.GetStatements.Add(new CodeMethodReturnStatement(
new CodeCastExpression(subClass.Name,
new CodeIndexerExpression(new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(), "List"),
new CodeArgumentReferenceExpression("index")))));
cmProperty.SetStatements.Add(new CodeAssignStatement(
new CodeIndexerExpression(new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(), "List"),
new CodeArgumentReferenceExpression("index")),
new CodeArgumentReferenceExpression("value")));
collectionClass.Members.Add(cmProperty);
cmProperty = new CodeMemberProperty();
cmProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final;
cmProperty.Name = element.QualifiedName.Name + "Collections";
cmProperty.HasGet = true;
cmProperty.Type = cmCollectionField.Type;
if (element.MinOccurs > 1)
{
}
else if (element.MinOccurs > 0)
{
}
else
{
}
cmProperty.GetStatements.Add(new CodeMethodReturnStatement(
new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(), "fld" + element.QualifiedName.Name + "Collection")));
tClass.Members.Add(cmProperty);
}
#endregion
#region else
else
{
tClass.Members.Add(cmField);
// add properties //
CodeMemberProperty cmProperty = new CodeMemberProperty();
cmProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final;
cmProperty.Name = element.QualifiedName.Name + "Field";
cmProperty.HasGet = true;
cmProperty.HasSet = true;
cmProperty.Type = cmField.Type;
cmProperty.GetStatements.Add(new CodeMethodReturnStatement(
new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(), "fld" + element.QualifiedName.Name)));
tClass.Members.Add(cmProperty);
tClass.Members.Add(subClass);
}
#endregion
//cmField.Comments.Add(new CodeCommentStatement(element.QualifiedName.Name + " field"));
////tClass.Members.Add(subClass);
#region if (flagTopElement)
if (flagTopElement)
{
// add Create method to AppConfigHandler class
CodeMemberMethod tMethod = new CodeMemberMethod();
tMethod.Name = "GetConfig";
tMethod.Attributes = MemberAttributes.Public | MemberAttributes.Static;
tMethod.ReturnType = new CodeTypeReference("AppConfig");
tMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), "sectionName"));
// add statement to Create method
tMethod.Statements.Add(new CodeSnippetStatement(@"
try
{
return (AppConfig)ConfigurationSettings.GetConfig(sectionName);
}
catch(Exception ex)
{
throw ex;
}
"));
tClass.Members.Add(tMethod);
flagTopElement = false;
OutputSchema(ct, tClass);
}
#endregion
#region else
else
{
sbField.Append(string.Format("private {0} {1} = {2};\r\n", element.SchemaTypeName.Name, element.QualifiedName.Name, element.DefaultValue));
// Declares a constructor that takes arguments
CodeConstructor targetConstructor = new CodeConstructor();
targetConstructor.Attributes = MemberAttributes.Public;
if (element.MaxOccurs > 1)
{
#region LoadAppValues Complex type
ceP = new CodeExpression[1];
csD = new CodeStatementCollection();
CodeIterationStatement codeWhile = new CodeIterationStatement();
codeWhile.TestExpression = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeVariableReferenceExpression("e" + element.QualifiedName.Name), "MoveNext"));
codeWhile.Statements.Add(new CodeVariableDeclarationStatement("XmlNode", "n" + element.QualifiedName.Name, new CodeCastExpression("XmlNode", new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("e" + element.QualifiedName.Name), "Current"))));
codeWhile.Statements.Add(new CodeSnippetStatement()); // empty line
OutputSchema(ct, subClass, targetConstructor, collectionClass, ref ceP, csD);
codeWhile.Statements.AddRange(csD);
codeWhile.Statements.Add(new CodeVariableDeclarationStatement(element.QualifiedName.Name + "Collection." + element.QualifiedName.Name, "l_" + element.QualifiedName.Name,
new CodeObjectCreateExpression(element.QualifiedName.Name + "Collection." + element.QualifiedName.Name, ceP)));
codeWhile.Statements.Add(new CodeSnippetStatement()); // empty line
codeWhile.Statements.Add(new CodeCommentStatement("add this " + element.QualifiedName.Name + " object to the collection"));
codeWhile.Statements.Add(
new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(
new CodeThisReferenceExpression(), "fld" + element.QualifiedName.Name + "Collection"), "Add",
new CodeVariableReferenceExpression("l_" + element.QualifiedName.Name)));
codeWhile.IncrementStatement = new CodeSnippetStatement("");
codeWhile.InitStatement = new CodeSnippetStatement("");
CodeStatement[] csStatements;
csStatements =
new CodeStatement[] {
new CodeSnippetStatement(), // empty line
new CodeAssignStatement(new CodeVariableReferenceExpression("nodeList"),
new CodeMethodInvokeExpression(
new CodeVariableReferenceExpression("currentConfigNode"), "SelectNodes",
new CodePrimitiveExpression(element.QualifiedName.Name))),
new CodeConditionStatement(
new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("nodeList"), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)),
new CodeStatement[]{
new CodeCommentStatement(""),
new CodeVariableDeclarationStatement("IEnumerator", "e" + element.QualifiedName.Name, new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeVariableReferenceExpression("nodeList"), "GetEnumerator"))),
codeWhile
})
};
if (tDeclaration != null)
tDeclaration.AddRange(csStatements);
else
loadAppValuesMethod.Statements.AddRange(csStatements);
#endregion
subClass.Members.Add(targetConstructor);
}
else
{
if ((tParameter.Length != 1) || (tParameter[0] != null))
{
CodeExpression[] ceTemp1 = new CodeExpression[tParameter.Length + 1];
tParameter.CopyTo(ceTemp1, 0);
tParameter = new CodeExpression[tParameter.Length + 1];
ceTemp1.CopyTo(tParameter, 0);
}
tParameter[tParameter.Length - 1] = new CodeVariableReferenceExpression("l_" + element.QualifiedName.Name);
#region LoadAppValues Complex type
ceP = new CodeExpression[1];
csD = new CodeStatementCollection();
OutputSchema(ct, subClass, targetConstructor, null, ref ceP, csD);
CodeStatementCollection csStatements = new CodeStatementCollection();
csStatements.Add(new CodeSnippetStatement()); // empty line
csStatements.Add(new CodeVariableDeclarationStatement("XmlNode", "n" + element.QualifiedName.Name,
new CodeMethodInvokeExpression(
new CodeVariableReferenceExpression(tClass.Name == "AppConfig" ? "currentConfigNode" : "n" + tClass.Name),
"SelectSingleNode",
new CodePrimitiveExpression(element.QualifiedName.Name))));
csStatements.AddRange(csD);
if (tClass.Name == "AppConfig")
{
csStatements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression("fld" + element.QualifiedName.Name),
new CodeObjectCreateExpression(element.QualifiedName.Name, ceP)));
}
else
{
csStatements.Add(new CodeVariableDeclarationStatement(tClass.Name + "Collection." + tClass.Name + "." + element.QualifiedName.Name,
"l_" + element.QualifiedName.Name,
new CodeObjectCreateExpression(tClass.Name + "Collection." + tClass.Name + "." + element.QualifiedName.Name, ceP)));
}
if (tDeclaration != null)
tDeclaration.AddRange(csStatements);
else
loadAppValuesMethod.Statements.AddRange(csStatements);
#endregion
subClass.Members.Add(targetConstructor);
}
}
#endregion
}
#endregion
#region else
else
{
// This is a plain ol' fashioned element.
sbOutput.Append(string.Format("\r\nPlain Element - Type - Default - MinOccur - MaxOccur: {0} - {1} - {2} - {3} - {4}", element.QualifiedName.Name, element.SchemaTypeName.Name, element.DefaultValue, element.MinOccurs, element.MaxOccurs));
// Declare the field.
CodeMemberField cmField = new CodeMemberField();
cmField.Attributes = MemberAttributes.Private;
cmField.Name = "fld" + element.QualifiedName.Name;
if (element.ElementSchemaType.Datatype != null)
cmType = System.Type.GetType(element.ElementSchemaType.Datatype.ValueType.FullName);
else
{
cmType = null;
cmTypeString = element.ElementSchemaType.Name;
}
if (cmType != null)
{
if (element.MaxOccurs > 1)
cmField.Type = new CodeTypeReference(new CodeTypeReference(cmType), 1); // declare array
else
cmField.Type = new CodeTypeReference(cmType);
}
else
{
if (element.MaxOccurs > 1)
cmField.Type = new CodeTypeReference(new CodeTypeReference(cmTypeString), 1); // declare array
else
cmField.Type = new CodeTypeReference(cmTypeString);
}
tClass.Members.Add(cmField);
// add properties //
CodeMemberProperty cmProperty = new CodeMemberProperty();
cmProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final;
cmProperty.Name = element.QualifiedName.Name;
cmProperty.HasGet = true;
cmProperty.Type = cmField.Type;
cmProperty.GetStatements.Add(new CodeMethodReturnStatement(
new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(), "fld" + element.QualifiedName.Name)));
tClass.Members.Add(cmProperty);
#region // LoadAppValues //
if (element.MaxOccurs > 1)
{
#region LoadAppValues Simple type
CodeVariableDeclarationStatement casNode;
casNode = new CodeVariableDeclarationStatement("XmlNodeList",
"nodeList" + element.QualifiedName.Name,
new CodeMethodInvokeExpression(
new CodeVariableReferenceExpression(tClass.Name == "AppConfig" ? "currentConfigNode" : "n" + tClass.Name), "SelectNodes",
new CodePrimitiveExpression(element.QualifiedName.Name)));
if (element.ElementSchemaType.Datatype != null)
cmType = System.Type.GetType(element.ElementSchemaType.Datatype.ValueType.FullName);
else
{
cmType = null;
cmTypeString = element.ElementSchemaType.Name;
}
if (cmType != null)
{
cmField.Type = new CodeTypeReference(new CodeTypeReference(cmType), 1); // declare array
}
else
{
cmField.Type = new CodeTypeReference(new CodeTypeReference(cmTypeString), 1); // declare array
}
if (tDeclaration != null)
{
if ((tParameter.Length != 1) || (tParameter[0] != null))
{
CodeExpression[] ceTemp1 = new CodeExpression[tParameter.Length + 1];
tParameter.CopyTo(ceTemp1, 0);
tParameter = new CodeExpression[tParameter.Length + 1];
ceTemp1.CopyTo(tParameter, 0);
}
tParameter[tParameter.Length - 1] = new CodeVariableReferenceExpression("l_fld" + element.QualifiedName.Name);
tDeclaration.Add(new CodeSnippetStatement()); // empty line
tDeclaration.Add(new CodeVariableDeclarationStatement(cmField.Type, "l_fld" + element.QualifiedName.Name, new CodePrimitiveExpression(null)));
tDeclaration.Add(casNode);
}
else
{
loadAppValuesMethod.Statements.Add(new CodeSnippetStatement()); // empty line
loadAppValuesMethod.Statements.Add(new CodeVariableDeclarationStatement(cmField.Type, "l_fld" + element.QualifiedName.Name, new CodePrimitiveExpression(null)));
loadAppValuesMethod.Statements.Add(casNode);
}
CodeBinaryOperatorExpression ifCondition1 = new CodeBinaryOperatorExpression();
ifCondition1.Left = new CodeVariableReferenceExpression("nodeList" + element.QualifiedName.Name);
ifCondition1.Right = new CodePrimitiveExpression(null);
ifCondition1.Operator = CodeBinaryOperatorType.IdentityInequality;
CodeBinaryOperatorExpression ifCondition2 = new CodeBinaryOperatorExpression();
ifCondition2.Left = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText"),
"Trim", null));
ifCondition2.Right = new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(typeof(string)), "Empty");
ifCondition2.Operator = CodeBinaryOperatorType.IdentityInequality;
CodeStatement[] csStatements;
CodeExpression ceTemp = null;
if (tDeclaration != null)
ceTemp = new CodeVariableReferenceExpression("l_fld" + element.QualifiedName.Name);
else
ceTemp = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "fld" + element.QualifiedName.Name);
if (cmType == typeof(int))
{
csStatements =
new CodeStatement[] {
new CodeTryCatchFinallyStatement(
new CodeStatement[]{
new CodeAssignStatement(ceTemp,
new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(int)), "Parse"),
new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText")))},
new CodeCatchClause[]{new CodeCatchClause(null, null, new CodeStatement[]{
new CodeThrowExceptionStatement(new CodeObjectCreateExpression(
new CodeTypeReference("Exception"), new CodeExpression[]{new CodePrimitiveExpression(element.QualifiedName.Name + @" must be an integer")}))
})})};
}
else if (cmType == typeof(bool))
{
csStatements =
new CodeStatement[] {
new CodeTryCatchFinallyStatement(
new CodeStatement[]{
new CodeAssignStatement(ceTemp,
new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(bool)), "Parse"),
new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText")))},
new CodeCatchClause[]{new CodeCatchClause(null, null, new CodeStatement[]{
new CodeThrowExceptionStatement(new CodeObjectCreateExpression(
new CodeTypeReference("Exception"), new CodeExpression[]{new CodePrimitiveExpression(element.QualifiedName.Name + @" must be a boolean")}))
})})};
}
else if (cmType == typeof(long))
{
csStatements =
new CodeStatement[] {
new CodeTryCatchFinallyStatement(
new CodeStatement[]{
new CodeAssignStatement(ceTemp,
new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(long)), "Parse"),
new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText")))},
new CodeCatchClause[]{new CodeCatchClause(null, null, new CodeStatement[]{
new CodeThrowExceptionStatement(new CodeObjectCreateExpression(
new CodeTypeReference("Exception"), new CodeExpression[]{new CodePrimitiveExpression(element.QualifiedName.Name + @" must be a long")}))
})})};
}
else
{
CodeIterationStatement codeWhile = new CodeIterationStatement();
codeWhile.TestExpression = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeVariableReferenceExpression("e" + element.QualifiedName.Name), "MoveNext"));
codeWhile.IncrementStatement = new CodeSnippetStatement("");
codeWhile.InitStatement = new CodeSnippetStatement("");
codeWhile.Statements.Add(new CodeVariableDeclarationStatement("XmlNode", "n" + element.QualifiedName.Name, new CodeCastExpression("XmlNode", new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("e" + element.QualifiedName.Name), "Current"))));
codeWhile.Statements.Add(new CodeSnippetStatement()); // empty line
codeWhile.Statements.Add(
new CodeAssignStatement(
new CodeArrayIndexerExpression(new CodeVariableReferenceExpression("l_fld" + element.QualifiedName.Name), new CodeVariableReferenceExpression("i++")),
new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("n" + element.QualifiedName.Name), "InnerText"))
);
if (cmType != null)
{
csStatements =
new CodeStatement[] {
new CodeAssignStatement(new CodeTypeReferenceExpression("l_fld" + element.QualifiedName.Name),
new CodeArrayCreateExpression(cmType, new CodePropertyReferenceExpression(new CodeTypeReferenceExpression("nodeList" + element.QualifiedName.Name), "Count"))),
new CodeVariableDeclarationStatement(typeof(int), "i", new CodePrimitiveExpression(0)),
new CodeVariableDeclarationStatement("IEnumerator", "e" + element.QualifiedName.Name, new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeVariableReferenceExpression("nodeList" + element.QualifiedName.Name), "GetEnumerator"))),
codeWhile
};
}
else
{
csStatements =
new CodeStatement[] {
new CodeAssignStatement(new CodeTypeReferenceExpression("l_fld" + element.QualifiedName.Name),
new CodeArrayCreateExpression(cmTypeString, new CodePropertyReferenceExpression(new CodeTypeReferenceExpression("nodeList" + element.QualifiedName.Name), "Count"))),
new CodeVariableDeclarationStatement(typeof(int), "i", new CodePrimitiveExpression(0)),
new CodeVariableDeclarationStatement("IEnumerator", "e" + element.QualifiedName.Name, new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeVariableReferenceExpression("nodeList" + element.QualifiedName.Name), "GetEnumerator"))),
codeWhile
};
}
}
CodeConditionStatement conditionalStatement = new CodeConditionStatement(
ifCondition1, // if (nodeList1 != null)
csStatements
);
if (tDeclaration != null)
tDeclaration.AddRange(new CodeStatement[] { conditionalStatement });
else
loadAppValuesMethod.Statements.AddRange(new CodeStatement[] { conditionalStatement });
#endregion
}
else
{
#region LoadAppValues Simple type
CodeAssignStatement casNode;
casNode = new CodeAssignStatement(
new CodeVariableReferenceExpression("node"),
new CodeMethodInvokeExpression(
new CodeVariableReferenceExpression(tClass.Name == "AppConfig" ? "currentConfigNode" : "n" + tClass.Name), "SelectSingleNode",
new CodePrimitiveExpression(element.QualifiedName.Name)));
if (element.ElementSchemaType.Datatype != null)
cmType = System.Type.GetType(element.ElementSchemaType.Datatype.ValueType.FullName);
else
{
cmType = null;
cmTypeString = element.ElementSchemaType.Name;
}
if (tDeclaration != null)
{
if ((tParameter.Length != 1) || (tParameter[0] != null))
{
CodeExpression[] ceTemp1 = new CodeExpression[tParameter.Length + 1];
tParameter.CopyTo(ceTemp1, 0);
tParameter = new CodeExpression[tParameter.Length + 1];
ceTemp1.CopyTo(tParameter, 0);
}
tParameter[tParameter.Length - 1] = new CodeVariableReferenceExpression("l_fld" + tClass.Name + "_" + element.QualifiedName.Name);
tDeclaration.Add(new CodeSnippetStatement()); // empty line
CodeExpression ceInit = null;
if (cmType == typeof(int))
ceInit = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(cmType), "MinValue");
else if (cmType == typeof(long))
ceInit = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(cmType), "MinValue");
else
{
if (cmType != null)
ceInit = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(cmType), "Empty");
else
ceInit = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(cmTypeString), "Empty");
}
if (cmType != null)
tDeclaration.Add(new CodeVariableDeclarationStatement(cmType, "l_fld" + tClass.Name + "_" + element.QualifiedName.Name, ceInit));
else
tDeclaration.Add(new CodeVariableDeclarationStatement(cmTypeString, "l_fld" + element.QualifiedName.Name, ceInit));
tDeclaration.Add(casNode);
}
else
{
loadAppValuesMethod.Statements.Add(new CodeSnippetStatement()); // empty line
loadAppValuesMethod.Statements.Add(casNode);
}
CodeBinaryOperatorExpression ifCondition1 = new CodeBinaryOperatorExpression();
ifCondition1.Left = new CodeVariableReferenceExpression("node");
ifCondition1.Right = new CodePrimitiveExpression(null);
ifCondition1.Operator = CodeBinaryOperatorType.IdentityInequality;
CodeBinaryOperatorExpression ifCondition2 = new CodeBinaryOperatorExpression();
ifCondition2.Left = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText"),
"Trim", null));
ifCondition2.Right = new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(typeof(string)), "Empty");
ifCondition2.Operator = CodeBinaryOperatorType.IdentityInequality;
CodeStatement[] csStatements;
CodeExpression ceTemp = null;
if (tDeclaration != null)
ceTemp = new CodeVariableReferenceExpression("l_fld" + tClass.Name + "_" + element.QualifiedName.Name);
else
ceTemp = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "fld" + element.QualifiedName.Name);
if (cmType == typeof(int))
{
csStatements =
new CodeStatement[] {
new CodeTryCatchFinallyStatement(
new CodeStatement[]{
new CodeAssignStatement(ceTemp,
new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(int)), "Parse"),
new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText")))},
new CodeCatchClause[]{new CodeCatchClause(null, null, new CodeStatement[]{
new CodeThrowExceptionStatement(new CodeObjectCreateExpression(
new CodeTypeReference("Exception"), new CodeExpression[]{new CodePrimitiveExpression(element.QualifiedName.Name + @" must be an integer")}))
})})};
}
else if (cmType == typeof(bool))
{
csStatements =
new CodeStatement[] {
new CodeTryCatchFinallyStatement(
new CodeStatement[]{
new CodeAssignStatement(ceTemp,
new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(bool)), "Parse"),
new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText")))},
new CodeCatchClause[]{new CodeCatchClause(null, null, new CodeStatement[]{
new CodeThrowExceptionStatement(new CodeObjectCreateExpression(
new CodeTypeReference("Exception"), new CodeExpression[]{new CodePrimitiveExpression(element.QualifiedName.Name + @" must be a bool")}))
})})};
}
else if (cmType == typeof(long))
{
csStatements =
new CodeStatement[] {
new CodeTryCatchFinallyStatement(
new CodeStatement[]{
new CodeAssignStatement(ceTemp,
new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(long)), "Parse"),
new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText")))},
new CodeCatchClause[]{new CodeCatchClause(null, null, new CodeStatement[]{
new CodeThrowExceptionStatement(new CodeObjectCreateExpression(
new CodeTypeReference("Exception"), new CodeExpression[]{new CodePrimitiveExpression(element.QualifiedName.Name + @" must be a long")}))
})})};
}
else
{
csStatements =
new CodeStatement[] {
new CodeAssignStatement(ceTemp,
new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText")) };
}
CodeConditionStatement conditionalStatement = new CodeConditionStatement(
new CodeBinaryOperatorExpression(ifCondition1, CodeBinaryOperatorType.BooleanAnd, ifCondition2),
csStatements
);
if (tDeclaration != null)
tDeclaration.AddRange(new CodeStatement[] { conditionalStatement });
else
loadAppValuesMethod.Statements.AddRange(new CodeStatement[] { conditionalStatement });
#endregion
}
#endregion
#region if (tConstructor != null)
if (tConstructor != null)
{
// constructor
tConstructor.Parameters.Add(new CodeParameterDeclarationExpression(cmField.Type, "_" + cmField.Name));
tConstructor.Statements.Add(
new CodeAssignStatement(new CodeVariableReferenceExpression(cmField.Name),
new CodeVariableReferenceExpression("_" + cmField.Name)));
if (tParentClass != null)
{
// GetIndexBy...
CodeMemberMethod tMethod = new CodeMemberMethod();
tMethod.Name = "GetIndexBy" + element.QualifiedName.Name;
tMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
tMethod.ReturnType = new CodeTypeReference(typeof(int));
tMethod.Parameters.Add(new CodeParameterDeclarationExpression(cmField.Type, "_" + element.QualifiedName.Name));
// add statement to Create method
tMethod.Statements.Add(new CodeSnippetStatement(@"
for (int i=0; i < List.Count; i++)
{
if ( ((" + tClass.Name + @")List[i])." + element.QualifiedName.Name + @" == _" + element.QualifiedName.Name + @")
{
return i;
}
}
throw new Exception(""Cannot identify " + element.QualifiedName.Name + @": "" + _" + element.QualifiedName.Name + @");
"));
tParentClass.Members.Add(tMethod);
}
}
#endregion
}
#endregion
}
else
// if a simple type, then add a tree node and recurse facets
if (simpleType != null)
{
sbOutput.Append("\r\nSimple Type: " + simpleType.QualifiedName.Name);
XmlSchemaSimpleTypeRestriction rest = simpleType.Content as XmlSchemaSimpleTypeRestriction;
if (rest != null)
{
foreach (XmlSchemaFacet schemaObject in rest.Facets)
{
sbOutput.Append("\r\nSimple Type Facet: " + schemaObject.GetType().FullName);
OutputSchema(schemaObject, tClass);
}
}
}
else
// if a complex type, add a tree node and recurse its sequence
if (complexType != null)
{
XmlSchemaSequence seq = complexType.Particle as XmlSchemaSequence;
if (seq != null)
{
foreach (XmlSchemaObject schemaObject in seq.Items)
{
OutputSchema(schemaObject, tClass, tConstructor, tParentClass, ref tParameter, tDeclaration);
}
}
}
// now recurse any object collection of the type.
foreach (PropertyInfo property in obj.GetType().GetProperties())
{
if (property.PropertyType.FullName == "System.Xml.Schema.XmlSchemaObjectCollection")
{
XmlSchemaObjectCollection childObjectCollection = (XmlSchemaObjectCollection)property.GetValue(obj, null);
foreach (XmlSchemaObject schemaObject in childObjectCollection)
{
sbOutput.Append("\r\nCollection: " + schemaObject.GetType().FullName);
OutputSchema(schemaObject, tClass);
}
}
}
}
#endregion
/// <summary>
/// Generate CSharp source code from the compile unit.
/// </summary>
/// <param name="filename">Output file name</param>
public void GenerateCSharpCode(string fileName)
{
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BracingStyle = "C";
using (StreamWriter sourceWriter = new StreamWriter(fileName))
{
provider.GenerateCodeFromCompileUnit(
targetUnit, sourceWriter, options);
}
}
private void SchemaEditor_Load(object sender, EventArgs e)
{
Process();
}
private void menuItem10_Click(object sender, EventArgs e)
{
InputBoxDialog ib = new InputBoxDialog();
ib.FormPrompt = "Input namespace for configuration class";
ib.FormCaption = "Namespace";
ib.DefaultValue = "";
ib.ShowDialog();
string s = ib.InputResponse;
ib.Close();
if (s.Trim().Length > 0)
outputNamespace = s;
}
}
}