[mapguide-commits] r5692 - in trunk/Tools/Maestro: Maestro Maestro.Base Maestro.Base/Editor Maestro.Base/Properties Maestro.Base/UI/Preferences Maestro.Editors/Generic OSGeo.MapGuide.MaestroAPI OSGeo.MapGuide.MaestroAPI/Properties OSGeo.MapGuide.MaestroAPI/Resource/Validation

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Mon Apr 11 10:34:42 EDT 2011


Author: jng
Date: 2011-04-11 07:34:42 -0700 (Mon, 11 Apr 2011)
New Revision: 5692

Added:
   trunk/Tools/Maestro/Maestro.Base/UI/Preferences/EditorPreferencesCtrl.Designer.cs
   trunk/Tools/Maestro/Maestro.Base/UI/Preferences/EditorPreferencesCtrl.cs
   trunk/Tools/Maestro/Maestro.Base/UI/Preferences/EditorPreferencesCtrl.resx
Modified:
   trunk/Tools/Maestro/Maestro.Base/Editor/XmlEditor.cs
   trunk/Tools/Maestro/Maestro.Base/Editor/XmlEditorDialog.cs
   trunk/Tools/Maestro/Maestro.Base/Maestro.Base.addin
   trunk/Tools/Maestro/Maestro.Base/Maestro.Base.csproj
   trunk/Tools/Maestro/Maestro.Base/Properties/Resources.Designer.cs
   trunk/Tools/Maestro/Maestro.Base/Properties/Resources.resx
   trunk/Tools/Maestro/Maestro.Base/UI/Preferences/ConfigProperties.cs
   trunk/Tools/Maestro/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.Designer.cs
   trunk/Tools/Maestro/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.cs
   trunk/Tools/Maestro/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.resx
   trunk/Tools/Maestro/Maestro.Editors/Generic/XmlEditorCtrl.cs
   trunk/Tools/Maestro/Maestro/Maestro.csproj
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/PlatformConnectionBase.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.Designer.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.resx
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ValidationResultSet.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/XmlValidator.cs
Log:
#1658: Support XML validation against local XSD files. Add a new preference which specifies the directory containing the MapGuide xsd schemas (default [AppDir]\Schemas)


Modified: trunk/Tools/Maestro/Maestro/Maestro.csproj
===================================================================
--- trunk/Tools/Maestro/Maestro/Maestro.csproj	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/Maestro/Maestro.csproj	2011-04-11 14:34:42 UTC (rev 5692)
@@ -138,6 +138,230 @@
       <DependentUpon>Resources.resx</DependentUpon>
       <DesignTime>True</DesignTime>
     </Compile>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\ApplicationDefinition-1.0.0.xsd">
+      <Link>Schemas\ApplicationDefinition-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\ApplicationDefinitionInfo-1.0.0.xsd">
+      <Link>Schemas\ApplicationDefinitionInfo-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\BatchPropertyCollection-1.0.0.xsd">
+      <Link>Schemas\BatchPropertyCollection-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\DataStoreList-1.0.0.xsd">
+      <Link>Schemas\DataStoreList-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\DrawingSectionList-1.0.0.xsd">
+      <Link>Schemas\DrawingSectionList-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\DrawingSectionResourceList-1.0.0.xsd">
+      <Link>Schemas\DrawingSectionResourceList-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\DrawingSource-1.0.0.xsd">
+      <Link>Schemas\DrawingSource-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\Envelope-1.0.0.xsd">
+      <Link>Schemas\Envelope-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\FdoLongTransactionList-1.0.0.xsd">
+      <Link>Schemas\FdoLongTransactionList-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\FdoProviderCapabilities-1.0.0.xsd">
+      <Link>Schemas\FdoProviderCapabilities-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\FdoProviderCapabilities-1.1.0.xsd">
+      <Link>Schemas\FdoProviderCapabilities-1.1.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\FdoSpatialContextList-1.0.0.xsd">
+      <Link>Schemas\FdoSpatialContextList-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\FeatureProviderRegistry-1.0.0.xsd">
+      <Link>Schemas\FeatureProviderRegistry-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\FeatureSet-1.0.0.xsd">
+      <Link>Schemas\FeatureSet-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\FeatureSource-1.0.0.xsd">
+      <Link>Schemas\FeatureSource-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\Group-1.0.0.xsd">
+      <Link>Schemas\Group-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\GroupList-1.0.0.xsd">
+      <Link>Schemas\GroupList-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\LayerDefinition-1.0.0.xsd">
+      <Link>Schemas\LayerDefinition-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\LayerDefinition-1.1.0.xsd">
+      <Link>Schemas\LayerDefinition-1.1.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\LayerDefinition-1.2.0.xsd">
+      <Link>Schemas\LayerDefinition-1.2.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\LayerDefinition-1.3.0.xsd">
+      <Link>Schemas\LayerDefinition-1.3.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\LoadProcedure-1.0.0.xsd">
+      <Link>Schemas\LoadProcedure-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\LoadProcedure-1.1.0.xsd">
+      <Link>Schemas\LoadProcedure-1.1.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\LoadProcedure-2.2.0.xsd">
+      <Link>Schemas\LoadProcedure-2.2.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\MapDefinition-1.0.0.xsd">
+      <Link>Schemas\MapDefinition-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\PlatformCommon-1.0.0.xsd">
+      <Link>Schemas\PlatformCommon-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\PrintLayout-1.0.0.xsd">
+      <Link>Schemas\PrintLayout-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\RepositoryContent-1.0.0.xsd">
+      <Link>Schemas\RepositoryContent-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\RepositoryList-1.0.0.xsd">
+      <Link>Schemas\RepositoryList-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\ResourceDataList-1.0.0.xsd">
+      <Link>Schemas\ResourceDataList-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\ResourceDocumentHeader-1.0.0.xsd">
+      <Link>Schemas\ResourceDocumentHeader-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\ResourceFolderHeader-1.0.0.xsd">
+      <Link>Schemas\ResourceFolderHeader-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\ResourceList-1.0.0.xsd">
+      <Link>Schemas\ResourceList-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\ResourcePackageManifest-1.0.0.xsd">
+      <Link>Schemas\ResourcePackageManifest-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\ResourceReferenceList-1.0.0.xsd">
+      <Link>Schemas\ResourceReferenceList-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\ResourceSecurity-1.0.0.xsd">
+      <Link>Schemas\ResourceSecurity-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\Role-1.0.0.xsd">
+      <Link>Schemas\Role-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\SelectAggregate-1.0.0.xsd">
+      <Link>Schemas\SelectAggregate-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\Server-1.0.0.xsd">
+      <Link>Schemas\Server-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\ServerList-1.0.0.xsd">
+      <Link>Schemas\ServerList-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\SiteInformation-1.0.0.xsd">
+      <Link>Schemas\SiteInformation-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\SiteInformation-2.2.0.xsd">
+      <Link>Schemas\SiteInformation-2.2.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\SiteStatus-2.2.0.xsd">
+      <Link>Schemas\SiteStatus-2.2.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\SiteVersion-1.0.0.xsd">
+      <Link>Schemas\SiteVersion-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\SiteVersion-2.2.0.xsd">
+      <Link>Schemas\SiteVersion-2.2.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\SqlSelect-1.0.0.xsd">
+      <Link>Schemas\SqlSelect-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\StringCollection-1.0.0.xsd">
+      <Link>Schemas\StringCollection-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\SymbolDefinition-1.0.0.xsd">
+      <Link>Schemas\SymbolDefinition-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\SymbolDefinition-1.1.0.xsd">
+      <Link>Schemas\SymbolDefinition-1.1.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\SymbolLibrary-1.0.0.xsd">
+      <Link>Schemas\SymbolLibrary-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\Types-1.0.0.xsd">
+      <Link>Schemas\Types-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\UnmanagedDataList-1.0.0.xsd">
+      <Link>Schemas\UnmanagedDataList-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\User-1.0.0.xsd">
+      <Link>Schemas\User-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\UserList-1.0.0.xsd">
+      <Link>Schemas\UserList-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\WebLayout-1.0.0.xsd">
+      <Link>Schemas\WebLayout-1.0.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Include="..\OSGeo.MapGuide.MaestroAPI\Schemas\WebLayout-1.1.0.xsd">
+      <Link>Schemas\WebLayout-1.1.0.xsd</Link>
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
     <None Include="App.config" />
     <None Include="Maestro.sh">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>

Modified: trunk/Tools/Maestro/Maestro.Base/Editor/XmlEditor.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/Editor/XmlEditor.cs	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/Maestro.Base/Editor/XmlEditor.cs	2011-04-11 14:34:42 UTC (rev 5692)
@@ -33,6 +33,8 @@
 using Maestro.Editors;
 using OSGeo.MapGuide.ObjectModels;
 using OSGeo.MapGuide.MaestroAPI.Resource.Validation;
+using System.Xml.Schema;
+using Maestro.Base.UI.Preferences;
 
 namespace Maestro.Base.Editor
 {
@@ -42,8 +44,15 @@
         {
             InitializeComponent();
             editor.Validator = new XmlValidationCallback(ValidateXml);
+            this.XsdPath = PropertyService.Get(ConfigProperties.XsdSchemaPath, ConfigProperties.DefaultXsdSchemaPath);
         }
 
+        public string XsdPath
+        {
+            get;
+            set;
+        }
+
         private void ValidateXml(out string[] errors, out string[] warnings)
         {
             errors = new string[0];
@@ -83,10 +92,68 @@
                 }
             }
 
+            //Finally verify the content itself
+            var xml = this.XmlContent;
+            var xsd = GetXsd(res.ValidatingSchema);
+            var validator = new XmlValidator();
+            using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
+            {
+                validator.Validate(ms, xsd);
+            }
+
+            err.AddRange(validator.ValidationErrors);
+            warn.AddRange(validator.ValidationWarnings);
+
+            /*
+            var xml = this.XmlContent;
+            var config = new XmlReaderSettings();
+            
+            config.ValidationType = ValidationType.Schema;
+            config.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
+            config.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
+            config.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
+            //This will trap all the errors and warnings that are raised
+            config.ValidationEventHandler += (s, e) =>
+            {
+                if (e.Severity == XmlSeverityType.Warning)
+                {
+                    warn.Add(e.Message);
+                }
+                else
+                {
+                    err.Add(e.Message);
+                }
+            };
+
+            using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
+            {
+                using (var reader = XmlReader.Create(ms, config))
+                {
+                    while (reader.Read()) { } //Trigger the validation
+                }
+            }*/
+
             errors = err.ToArray();
             warnings = warn.ToArray();
         }
 
+        private XmlSchema GetXsd(string xsdFile)
+        {
+            string path = xsdFile;
+
+            if (!string.IsNullOrEmpty(this.XsdPath))
+                path = Path.Combine(this.XsdPath, xsdFile);
+
+            if (File.Exists(path))
+            {
+                ValidationEventHandler handler = (s, e) =>
+                {
+                };
+                return XmlSchema.Read(File.OpenRead(path), handler);
+            }
+            return null;
+        }
+
         private IEditorService _edSvc;
 
         protected override void Bind(IEditorService service)
@@ -119,7 +186,9 @@
 
             //Put through ValidationResultSet to weed out redundant messages
             var set = new ValidationResultSet(issues);
-            return set.GetAllIssues();
+
+            //Only care about errors. Warnings and other types should not derail us from saving
+            return set.GetAllIssues(ValidationStatus.Error);
         }
 
         public override string GetXmlContent()

Modified: trunk/Tools/Maestro/Maestro.Base/Editor/XmlEditorDialog.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/Editor/XmlEditorDialog.cs	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/Maestro.Base/Editor/XmlEditorDialog.cs	2011-04-11 14:34:42 UTC (rev 5692)
@@ -29,6 +29,9 @@
 using OSGeo.MapGuide.MaestroAPI;
 using System.Xml;
 using Maestro.Editors;
+using System.Xml.Schema;
+using Maestro.Base.UI.Preferences;
+using ICSharpCode.Core;
 
 namespace Maestro.Base.Editor
 {
@@ -44,8 +47,15 @@
             _ed.Validator = new XmlValidationCallback(ValidateXml);
             _ed.Dock = DockStyle.Fill;
             contentPanel.Controls.Add(_ed);
+            this.XsdPath = PropertyService.Get(ConfigProperties.XsdSchemaPath, ConfigProperties.DefaultXsdSchemaPath);
         }
 
+        public string XsdPath
+        {
+            get;
+            set;
+        }
+
         public XmlEditorDialog(IEditorService edsvc)
             : this()
         {
@@ -81,6 +91,43 @@
             private set;
         }
 
+        private bool _enableResourceTypeValidation = false;
+
+        public void SetXmlContent(string xml, ResourceTypes type)
+        {
+            _ed.XmlContent = xml;
+            this.ResourceType = type;
+            _enableResourceTypeValidation = true;
+        }
+
+        private string _lastSnapshot;
+
+        /// <summary>
+        /// Gets or sets the XML content for this dialog.
+        /// </summary>
+        public string XmlContent
+        {
+            get { return _ed.XmlContent; }
+            set { _ed.XmlContent = _lastSnapshot = value; }
+        }
+
+        private XmlSchema GetXsd(string xsdFile)
+        {
+            string path = xsdFile;
+
+            if (!string.IsNullOrEmpty(this.XsdPath))
+                path = Path.Combine(this.XsdPath, xsdFile);
+
+            if (File.Exists(path))
+            {
+                ValidationEventHandler handler = (s, e) =>
+                {
+                };
+                return XmlSchema.Read(File.OpenRead(path), handler);
+            }
+            return null;
+        }
+
         private void ValidateXml(out string[] errors, out string[] warnings)
         {
             errors = new string[0];
@@ -89,59 +136,80 @@
             List<string> err = new List<string>();
             List<string> warn = new List<string>();
 
-            var res = this.ResourceType;
+            var res = _edSvc.GetEditedResource();
 
             //Test for well-formedness
             try
             {
                 XmlDocument doc = new XmlDocument();
-                doc.LoadXml(this.XmlContent);
+                doc.LoadXml(_ed.XmlContent);
             }
             catch (XmlException ex)
             {
                 err.Add(ex.Message);
             }
 
-            //Test that this is serializable
-            try
+            //If strongly-typed, test that this is serializable
+            if (res.IsStronglyTyped)
             {
-                if (_enableResourceTypeValidation)
+                try
                 {
                     //Test by simply attempting to deserialize the current xml content
-                    using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(this.XmlContent)))
+                    using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(_ed.XmlContent)))
                     {
                         //Use original resource type to determine how to deserialize
-                        var obj = ResourceTypeRegistry.Deserialize(this.ResourceType, ms);
+                        var obj = ResourceTypeRegistry.Deserialize(res.ResourceType, ms);
                     }
                 }
+                catch (Exception ex)
+                {
+                    err.Add(ex.Message);
+                }
             }
-            catch (Exception ex)
+
+            //Finally verify the content itself
+            var xml = this.XmlContent;
+            var xsd = GetXsd(res.ValidatingSchema);
+            var validator = new XmlValidator();
+            using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
             {
-                err.Add(ex.Message);
+                validator.Validate(ms, xsd);
             }
 
-            errors = err.ToArray();
-            warnings = warn.ToArray();
-        }
+            err.AddRange(validator.ValidationErrors);
+            warn.AddRange(validator.ValidationWarnings);
 
-        private bool _enableResourceTypeValidation = false;
+            /*
+            var xml = this.XmlContent;
+            var config = new XmlReaderSettings();
+            
+            config.ValidationType = ValidationType.Schema;
+            config.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
+            config.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
+            config.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
+            //This will trap all the errors and warnings that are raised
+            config.ValidationEventHandler += (s, e) =>
+            {
+                if (e.Severity == XmlSeverityType.Warning)
+                {
+                    warn.Add(e.Message);
+                }
+                else
+                {
+                    err.Add(e.Message);
+                }
+            };
 
-        public void SetXmlContent(string xml, ResourceTypes type)
-        {
-            _ed.XmlContent = xml;
-            this.ResourceType = type;
-            _enableResourceTypeValidation = true;
-        }
+            using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
+            {
+                using (var reader = XmlReader.Create(ms, config))
+                {
+                    while (reader.Read()) { } //Trigger the validation
+                }
+            }*/
 
-        private string _lastSnapshot;
-
-        /// <summary>
-        /// Gets or sets the XML content for this dialog.
-        /// </summary>
-        public string XmlContent
-        {
-            get { return _ed.XmlContent; }
-            set { _ed.XmlContent = _lastSnapshot = value; }
+            errors = err.ToArray();
+            warnings = warn.ToArray();
         }
 
         private void btnCancel_Click(object sender, EventArgs e)
@@ -151,9 +219,12 @@
 
         private void btnSave_Click(object sender, EventArgs e)
         {
-            if (_lastSnapshot != _ed.XmlContent)
-                OnResourceChanged();
-            this.DialogResult = DialogResult.OK;
+            if (_ed.PerformValidation(true, true))
+            {
+                if (_lastSnapshot != _ed.XmlContent)
+                    OnResourceChanged();
+                this.DialogResult = DialogResult.OK;
+            }
         }
 
         private void OnResourceChanged()

Modified: trunk/Tools/Maestro/Maestro.Base/Maestro.Base.addin
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/Maestro.Base.addin	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/Maestro.Base/Maestro.Base.addin	2011-04-11 14:34:42 UTC (rev 5692)
@@ -28,6 +28,7 @@
     <!-- Registered preference tabs -->
     <Path name="/Maestro/Preferences">
         <Class id="GeneralPrefs" class="Maestro.Base.UI.Preferences.GeneralPreferencesCtrl" />
+        <Class id="EditorPrefs" class="Maestro.Base.UI.Preferences.EditorPreferencesCtrl" />
     </Path>
 
     <!-- Registered drop handlers -->

Modified: trunk/Tools/Maestro/Maestro.Base/Maestro.Base.csproj
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/Maestro.Base.csproj	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/Maestro.Base/Maestro.Base.csproj	2011-04-11 14:34:42 UTC (rev 5692)
@@ -289,6 +289,12 @@
       <DependentUpon>CreatePackageDialog.cs</DependentUpon>
     </Compile>
     <Compile Include="UI\Preferences\ConfigProperties.cs" />
+    <Compile Include="UI\Preferences\EditorPreferencesCtrl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="UI\Preferences\EditorPreferencesCtrl.Designer.cs">
+      <DependentUpon>EditorPreferencesCtrl.cs</DependentUpon>
+    </Compile>
     <Compile Include="UI\Preferences\GeneralPreferencesCtrl.cs">
       <SubType>UserControl</SubType>
     </Compile>
@@ -490,6 +496,9 @@
     <EmbeddedResource Include="UI\Packaging\CreatePackageDialog.resx">
       <DependentUpon>CreatePackageDialog.cs</DependentUpon>
     </EmbeddedResource>
+    <EmbeddedResource Include="UI\Preferences\EditorPreferencesCtrl.resx">
+      <DependentUpon>EditorPreferencesCtrl.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="UI\Preferences\GeneralPreferencesCtrl.resx">
       <DependentUpon>GeneralPreferencesCtrl.cs</DependentUpon>
     </EmbeddedResource>

Modified: trunk/Tools/Maestro/Maestro.Base/Properties/Resources.Designer.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/Properties/Resources.Designer.cs	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/Maestro.Base/Properties/Resources.Designer.cs	2011-04-11 14:34:42 UTC (rev 5692)
@@ -1231,6 +1231,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Editors.
+        /// </summary>
+        internal static string Prefs_Editor {
+            get {
+                return ResourceManager.GetString("Prefs_Editor", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to General.
         /// </summary>
         internal static string Prefs_General {

Modified: trunk/Tools/Maestro/Maestro.Base/Properties/Resources.resx
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/Properties/Resources.resx	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/Maestro.Base/Properties/Resources.resx	2011-04-11 14:34:42 UTC (rev 5692)
@@ -977,4 +977,7 @@
   <data name="TPL_USER_DEFINED" xml:space="preserve">
     <value>User Defined Resource Templates</value>
   </data>
+  <data name="Prefs_Editor" xml:space="preserve">
+    <value>Editors</value>
+  </data>
 </root>
\ No newline at end of file

Modified: trunk/Tools/Maestro/Maestro.Base/UI/Preferences/ConfigProperties.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/UI/Preferences/ConfigProperties.cs	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/Maestro.Base/UI/Preferences/ConfigProperties.cs	2011-04-11 14:34:42 UTC (rev 5692)
@@ -38,18 +38,50 @@
         public const string MgCookerPath = "General.MgCookerPath";
         public const string LocalFsPreviewPath = "General.LocalFsPreviewPath";
         public const string ValidateOnSave = "General.ValidateResourceOnSave";
+        public const string XsdSchemaPath = "Editor.XsdSchemaPath";
 
         internal static void ApplyDefaults()
         {
-            Props.Set(ConfigProperties.PreviewViewerType, "AJAX");
-            Props.Set(ConfigProperties.UserTemplatesDirectory, Path.Combine(FileUtility.ApplicationRootPath, "UserTemplates"));
-            Props.Set(ConfigProperties.ShowMessages, true);
-            Props.Set(ConfigProperties.ShowOutboundRequests, true);
-            Props.Set(ConfigProperties.OpenColor, Color.LightGreen);
-            Props.Set(ConfigProperties.DirtyColor, Color.Pink);
-            Props.Set(ConfigProperties.MgCookerPath, Path.Combine(FileUtility.ApplicationRootPath, "MgCooker.exe"));
-            Props.Set(ConfigProperties.LocalFsPreviewPath, Path.Combine(FileUtility.ApplicationRootPath, "MaestroFsPreview.exe"));
-            Props.Set(ConfigProperties.ValidateOnSave, true);
+            ApplyGeneralDefaults();
+            ApplyEditorDefaults();
         }
+
+        internal static void ApplyEditorDefaults()
+        {
+            Props.Set(ConfigProperties.ValidateOnSave, DefaultValidateOnSave);
+            Props.Set(ConfigProperties.XsdSchemaPath, DefaultXsdSchemaPath);
+        }
+
+        internal static void ApplyGeneralDefaults()
+        {
+            Props.Set(ConfigProperties.PreviewViewerType, DefaultPreviewViewerType);
+            Props.Set(ConfigProperties.UserTemplatesDirectory, DefaultUserTemplatesDirectory);
+            Props.Set(ConfigProperties.ShowMessages, DefaultShowMessages);
+            Props.Set(ConfigProperties.ShowOutboundRequests, DefaultShowOutboundRequests);
+            Props.Set(ConfigProperties.OpenColor, DefaultOpenColor);
+            Props.Set(ConfigProperties.DirtyColor, DefaultDirtyColor);
+            Props.Set(ConfigProperties.MgCookerPath, DefaultMgCookerPath);
+            Props.Set(ConfigProperties.LocalFsPreviewPath, DefaultLocalFsPreviewPath);
+        }
+
+        public static string DefaultMgCookerPath { get { return Path.Combine(FileUtility.ApplicationRootPath, "MgCooker.exe"); } }
+
+        public static string DefaultLocalFsPreviewPath { get { return Path.Combine(FileUtility.ApplicationRootPath, "MaestroFsPreview.exe"); } }
+
+        public static Color DefaultOpenColor { get { return Color.LightGreen; } }
+
+        public static Color DefaultDirtyColor { get { return Color.Pink; } }
+
+        public static bool DefaultShowMessages { get { return true; } }
+
+        public static bool DefaultShowOutboundRequests { get { return true; } }
+
+        public static bool DefaultValidateOnSave { get { return true; } }
+
+        public static string DefaultXsdSchemaPath { get { return Path.Combine(FileUtility.ApplicationRootPath, "Schemas"); } }
+
+        public static string DefaultPreviewViewerType { get { return "AJAX"; } }
+
+        public static string DefaultUserTemplatesDirectory { get { return Path.Combine(FileUtility.ApplicationRootPath, "UserTemplates"); } }
     }
 }

Added: trunk/Tools/Maestro/Maestro.Base/UI/Preferences/EditorPreferencesCtrl.Designer.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/UI/Preferences/EditorPreferencesCtrl.Designer.cs	                        (rev 0)
+++ trunk/Tools/Maestro/Maestro.Base/UI/Preferences/EditorPreferencesCtrl.Designer.cs	2011-04-11 14:34:42 UTC (rev 5692)
@@ -0,0 +1,135 @@
+namespace Maestro.Base.UI.Preferences
+{
+    partial class EditorPreferencesCtrl
+    {
+        /// <summary> 
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Component 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.groupBox4 = new System.Windows.Forms.GroupBox();
+            this.chkValidateOnSave = new System.Windows.Forms.CheckBox();
+            this.groupBox1 = new System.Windows.Forms.GroupBox();
+            this.btnBrowseXsdPath = new System.Windows.Forms.Button();
+            this.txtXsdPath = new System.Windows.Forms.TextBox();
+            this.label4 = new System.Windows.Forms.Label();
+            this.groupBox4.SuspendLayout();
+            this.groupBox1.SuspendLayout();
+            this.SuspendLayout();
+            // 
+            // groupBox4
+            // 
+            this.groupBox4.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.groupBox4.Controls.Add(this.chkValidateOnSave);
+            this.groupBox4.Location = new System.Drawing.Point(3, 3);
+            this.groupBox4.Name = "groupBox4";
+            this.groupBox4.Size = new System.Drawing.Size(399, 50);
+            this.groupBox4.TabIndex = 10;
+            this.groupBox4.TabStop = false;
+            this.groupBox4.Text = "Editing";
+            // 
+            // chkValidateOnSave
+            // 
+            this.chkValidateOnSave.AutoSize = true;
+            this.chkValidateOnSave.ImeMode = System.Windows.Forms.ImeMode.NoControl;
+            this.chkValidateOnSave.Location = new System.Drawing.Point(19, 19);
+            this.chkValidateOnSave.Name = "chkValidateOnSave";
+            this.chkValidateOnSave.Size = new System.Drawing.Size(163, 17);
+            this.chkValidateOnSave.TabIndex = 2;
+            this.chkValidateOnSave.Text = "Validate Resources On Save";
+            this.chkValidateOnSave.UseVisualStyleBackColor = true;
+            // 
+            // groupBox1
+            // 
+            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.groupBox1.Controls.Add(this.btnBrowseXsdPath);
+            this.groupBox1.Controls.Add(this.label4);
+            this.groupBox1.Controls.Add(this.txtXsdPath);
+            this.groupBox1.Location = new System.Drawing.Point(4, 60);
+            this.groupBox1.Name = "groupBox1";
+            this.groupBox1.Size = new System.Drawing.Size(398, 66);
+            this.groupBox1.TabIndex = 11;
+            this.groupBox1.TabStop = false;
+            this.groupBox1.Text = "XML Editor";
+            // 
+            // btnBrowseXsdPath
+            // 
+            this.btnBrowseXsdPath.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnBrowseXsdPath.ImeMode = System.Windows.Forms.ImeMode.NoControl;
+            this.btnBrowseXsdPath.Location = new System.Drawing.Point(367, 22);
+            this.btnBrowseXsdPath.Name = "btnBrowseXsdPath";
+            this.btnBrowseXsdPath.Size = new System.Drawing.Size(25, 23);
+            this.btnBrowseXsdPath.TabIndex = 14;
+            this.btnBrowseXsdPath.Text = "...";
+            this.btnBrowseXsdPath.UseVisualStyleBackColor = true;
+            this.btnBrowseXsdPath.Click += new System.EventHandler(this.btnBrowseXsdPath_Click);
+            // 
+            // txtXsdPath
+            // 
+            this.txtXsdPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtXsdPath.Location = new System.Drawing.Point(112, 24);
+            this.txtXsdPath.Name = "txtXsdPath";
+            this.txtXsdPath.ReadOnly = true;
+            this.txtXsdPath.Size = new System.Drawing.Size(249, 20);
+            this.txtXsdPath.TabIndex = 13;
+            // 
+            // label4
+            // 
+            this.label4.AutoSize = true;
+            this.label4.ImeMode = System.Windows.Forms.ImeMode.NoControl;
+            this.label4.Location = new System.Drawing.Point(15, 27);
+            this.label4.Name = "label4";
+            this.label4.Size = new System.Drawing.Size(91, 13);
+            this.label4.TabIndex = 12;
+            this.label4.Text = "Xml Schema Path";
+            // 
+            // EditorPreferencesCtrl
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.groupBox1);
+            this.Controls.Add(this.groupBox4);
+            this.Name = "EditorPreferencesCtrl";
+            this.Size = new System.Drawing.Size(405, 326);
+            this.groupBox4.ResumeLayout(false);
+            this.groupBox4.PerformLayout();
+            this.groupBox1.ResumeLayout(false);
+            this.groupBox1.PerformLayout();
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.GroupBox groupBox4;
+        private System.Windows.Forms.CheckBox chkValidateOnSave;
+        private System.Windows.Forms.GroupBox groupBox1;
+        private System.Windows.Forms.Button btnBrowseXsdPath;
+        private System.Windows.Forms.TextBox txtXsdPath;
+        private System.Windows.Forms.Label label4;
+    }
+}

Added: trunk/Tools/Maestro/Maestro.Base/UI/Preferences/EditorPreferencesCtrl.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/UI/Preferences/EditorPreferencesCtrl.cs	                        (rev 0)
+++ trunk/Tools/Maestro/Maestro.Base/UI/Preferences/EditorPreferencesCtrl.cs	2011-04-11 14:34:42 UTC (rev 5692)
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using Props = ICSharpCode.Core.PropertyService;
+using System.Windows.Forms;
+
+namespace Maestro.Base.UI.Preferences
+{
+    public partial class EditorPreferencesCtrl : UserControl, IPreferenceSheet
+    {
+        public EditorPreferencesCtrl()
+        {
+            InitializeComponent();
+        }
+
+        private void btnBrowseXsdPath_Click(object sender, EventArgs e)
+        {
+            using (var browser = new FolderBrowserDialog())
+            {
+                browser.ShowNewFolderButton = true;
+                if (browser.ShowDialog() == DialogResult.OK)
+                {
+                    txtXsdPath.Text = browser.SelectedPath;
+                }
+            }
+        }
+
+        protected override void OnLoad(EventArgs e)
+        {
+            base.OnLoad(e);
+
+            var validate = Props.Get(ConfigProperties.ValidateOnSave, ConfigProperties.DefaultValidateOnSave);
+            chkValidateOnSave.Checked = validate;
+
+            var path = Props.Get(ConfigProperties.XsdSchemaPath, ConfigProperties.DefaultXsdSchemaPath);
+            txtXsdPath.Text = path;
+        }
+
+        public string Title
+        {
+            get { return Properties.Resources.Prefs_Editor; }
+        }
+
+        public Control ContentControl
+        {
+            get { return this; }
+        }
+
+        public bool ApplyChanges()
+        {
+            bool restart = false;
+
+            Apply(ConfigProperties.ValidateOnSave, chkValidateOnSave.Checked);
+
+            //These changes require restart
+            if (Apply(ConfigProperties.XsdSchemaPath, txtXsdPath.Text))
+                restart = true;
+
+            return restart;
+        }
+
+        private bool Apply<T>(string key, T newValue)
+        {
+            if (Props.Get(key).Equals((object)newValue))
+                return false;
+
+            Props.Set(key, newValue);
+            return true;
+        }
+
+        public void ApplyDefaults()
+        {
+            ConfigProperties.ApplyEditorDefaults();
+        }
+    }
+}

Added: trunk/Tools/Maestro/Maestro.Base/UI/Preferences/EditorPreferencesCtrl.resx
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/UI/Preferences/EditorPreferencesCtrl.resx	                        (rev 0)
+++ trunk/Tools/Maestro/Maestro.Base/UI/Preferences/EditorPreferencesCtrl.resx	2011-04-11 14:34:42 UTC (rev 5692)
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file

Modified: trunk/Tools/Maestro/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.Designer.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.Designer.cs	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.Designer.cs	2011-04-11 14:34:42 UTC (rev 5692)
@@ -50,12 +50,9 @@
             this.cmbOpenedColor = new Maestro.Editors.Common.ColorComboBox();
             this.label6 = new System.Windows.Forms.Label();
             this.label5 = new System.Windows.Forms.Label();
-            this.groupBox4 = new System.Windows.Forms.GroupBox();
-            this.chkValidateOnSave = new System.Windows.Forms.CheckBox();
             this.groupBox1.SuspendLayout();
             this.groupBox2.SuspendLayout();
             this.groupBox3.SuspendLayout();
-            this.groupBox4.SuspendLayout();
             this.SuspendLayout();
             // 
             // label1
@@ -195,23 +192,9 @@
             resources.ApplyResources(this.label5, "label5");
             this.label5.Name = "label5";
             // 
-            // groupBox4
-            // 
-            this.groupBox4.Controls.Add(this.chkValidateOnSave);
-            resources.ApplyResources(this.groupBox4, "groupBox4");
-            this.groupBox4.Name = "groupBox4";
-            this.groupBox4.TabStop = false;
-            // 
-            // chkValidateOnSave
-            // 
-            resources.ApplyResources(this.chkValidateOnSave, "chkValidateOnSave");
-            this.chkValidateOnSave.Name = "chkValidateOnSave";
-            this.chkValidateOnSave.UseVisualStyleBackColor = true;
-            // 
             // GeneralPreferencesCtrl
             // 
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
-            this.Controls.Add(this.groupBox4);
             this.Controls.Add(this.groupBox3);
             this.Controls.Add(this.groupBox2);
             this.Controls.Add(this.groupBox1);
@@ -229,8 +212,6 @@
             this.groupBox2.PerformLayout();
             this.groupBox3.ResumeLayout(false);
             this.groupBox3.PerformLayout();
-            this.groupBox4.ResumeLayout(false);
-            this.groupBox4.PerformLayout();
             this.ResumeLayout(false);
             this.PerformLayout();
 
@@ -259,7 +240,5 @@
         private System.Windows.Forms.Label label5;
         private Maestro.Editors.Common.ColorComboBox cmbModifiedColor;
         private Maestro.Editors.Common.ColorComboBox cmbOpenedColor;
-        private System.Windows.Forms.GroupBox groupBox4;
-        private System.Windows.Forms.CheckBox chkValidateOnSave;
     }
 }

Modified: trunk/Tools/Maestro/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.cs	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.cs	2011-04-11 14:34:42 UTC (rev 5692)
@@ -56,11 +56,10 @@
             chkMessages.Checked = msg;
             var outb = Props.Get(ConfigProperties.ShowOutboundRequests, true);
             chkOutbound.Checked = outb;
-            var validate = Props.Get(ConfigProperties.ValidateOnSave, true);
-            chkValidateOnSave.Checked = validate;
+            
 
-            txtFsPreview.Text = Props.Get(ConfigProperties.LocalFsPreviewPath, "");
-            txtMgCooker.Text = Props.Get(ConfigProperties.MgCookerPath, "");
+            txtFsPreview.Text = Props.Get(ConfigProperties.LocalFsPreviewPath, ConfigProperties.DefaultLocalFsPreviewPath);
+            txtMgCooker.Text = Props.Get(ConfigProperties.MgCookerPath, ConfigProperties.DefaultMgCookerPath);
 
             cmbOpenedColor.CurrentColor = Props.Get(ConfigProperties.OpenColor, Color.LightGreen);
             cmbModifiedColor.CurrentColor = Props.Get(ConfigProperties.DirtyColor, Color.Pink);
@@ -100,7 +99,6 @@
             Apply(ConfigProperties.LocalFsPreviewPath, txtFsPreview.Text);
             Apply(ConfigProperties.OpenColor, (Color)cmbOpenedColor.CurrentColor);
             Apply(ConfigProperties.DirtyColor, (Color)cmbModifiedColor.CurrentColor);
-            Apply(ConfigProperties.ValidateOnSave, chkValidateOnSave.Checked);
 
             //These changes require restart
             if (Apply(ConfigProperties.ShowMessages, chkMessages.Checked ? "True" : "False"))
@@ -126,7 +124,7 @@
 
         public void ApplyDefaults()
         {
-            ConfigProperties.ApplyDefaults();
+            ConfigProperties.ApplyGeneralDefaults();
         }
 
         private void btnBrowseMgCooker_Click(object sender, EventArgs e)

Modified: trunk/Tools/Maestro/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.resx
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.resx	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/Maestro.Base/UI/Preferences/GeneralPreferencesCtrl.resx	2011-04-11 14:34:42 UTC (rev 5692)
@@ -144,7 +144,7 @@
     <value>$this</value>
   </data>
   <data name="&gt;&gt;label1.ZOrder" xml:space="preserve">
-    <value>9</value>
+    <value>8</value>
   </data>
   <data name="rdAjax.AutoSize" type="System.Boolean, mscorlib">
     <value>True</value>
@@ -171,7 +171,7 @@
     <value>$this</value>
   </data>
   <data name="&gt;&gt;rdAjax.ZOrder" xml:space="preserve">
-    <value>8</value>
+    <value>7</value>
   </data>
   <data name="rdFusion.AutoSize" type="System.Boolean, mscorlib">
     <value>True</value>
@@ -201,13 +201,13 @@
     <value>$this</value>
   </data>
   <data name="&gt;&gt;rdFusion.ZOrder" xml:space="preserve">
-    <value>7</value>
+    <value>6</value>
   </data>
   <data name="label2.AutoSize" type="System.Boolean, mscorlib">
     <value>True</value>
   </data>
   <data name="label2.Location" type="System.Drawing.Point, System.Drawing">
-    <value>13, 42</value>
+    <value>13, 52</value>
   </data>
   <data name="label2.Size" type="System.Drawing.Size, System.Drawing">
     <value>101, 13</value>
@@ -228,14 +228,14 @@
     <value>$this</value>
   </data>
   <data name="&gt;&gt;label2.ZOrder" xml:space="preserve">
-    <value>6</value>
+    <value>5</value>
   </data>
   <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
   <data name="txtTemplatePath.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
     <value>Top, Left, Right</value>
   </data>
   <data name="txtTemplatePath.Location" type="System.Drawing.Point, System.Drawing">
-    <value>120, 39</value>
+    <value>120, 49</value>
   </data>
   <data name="txtTemplatePath.Size" type="System.Drawing.Size, System.Drawing">
     <value>291, 20</value>
@@ -253,13 +253,13 @@
     <value>$this</value>
   </data>
   <data name="&gt;&gt;txtTemplatePath.ZOrder" xml:space="preserve">
-    <value>5</value>
+    <value>4</value>
   </data>
   <data name="btnBrowseTemplatePath.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
     <value>Top, Right</value>
   </data>
   <data name="btnBrowseTemplatePath.Location" type="System.Drawing.Point, System.Drawing">
-    <value>417, 37</value>
+    <value>417, 47</value>
   </data>
   <data name="btnBrowseTemplatePath.Size" type="System.Drawing.Size, System.Drawing">
     <value>25, 23</value>
@@ -280,7 +280,7 @@
     <value>$this</value>
   </data>
   <data name="&gt;&gt;btnBrowseTemplatePath.ZOrder" xml:space="preserve">
-    <value>4</value>
+    <value>3</value>
   </data>
   <data name="groupBox1.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
     <value>Top, Left, Right</value>
@@ -340,7 +340,7 @@
     <value>1</value>
   </data>
   <data name="groupBox1.Location" type="System.Drawing.Point, System.Drawing">
-    <value>16, 127</value>
+    <value>16, 93</value>
   </data>
   <data name="groupBox1.Size" type="System.Drawing.Size, System.Drawing">
     <value>426, 50</value>
@@ -361,7 +361,7 @@
     <value>$this</value>
   </data>
   <data name="&gt;&gt;groupBox1.ZOrder" xml:space="preserve">
-    <value>3</value>
+    <value>2</value>
   </data>
   <data name="groupBox2.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
     <value>Top, Left, Right</value>
@@ -523,10 +523,10 @@
     <value>5</value>
   </data>
   <data name="groupBox2.Location" type="System.Drawing.Point, System.Drawing">
-    <value>16, 266</value>
+    <value>16, 245</value>
   </data>
   <data name="groupBox2.Size" type="System.Drawing.Size, System.Drawing">
-    <value>426, 78</value>
+    <value>426, 94</value>
   </data>
   <data name="groupBox2.TabIndex" type="System.Int32, mscorlib">
     <value>7</value>
@@ -544,7 +544,7 @@
     <value>$this</value>
   </data>
   <data name="&gt;&gt;groupBox2.ZOrder" xml:space="preserve">
-    <value>2</value>
+    <value>1</value>
   </data>
   <data name="groupBox3.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
     <value>Top, Left, Right</value>
@@ -646,10 +646,10 @@
     <value>3</value>
   </data>
   <data name="groupBox3.Location" type="System.Drawing.Point, System.Drawing">
-    <value>16, 183</value>
+    <value>16, 149</value>
   </data>
   <data name="groupBox3.Size" type="System.Drawing.Size, System.Drawing">
-    <value>426, 77</value>
+    <value>426, 90</value>
   </data>
   <data name="groupBox3.TabIndex" type="System.Int32, mscorlib">
     <value>8</value>
@@ -667,62 +667,8 @@
     <value>$this</value>
   </data>
   <data name="&gt;&gt;groupBox3.ZOrder" xml:space="preserve">
-    <value>1</value>
-  </data>
-  <data name="chkValidateOnSave.AutoSize" type="System.Boolean, mscorlib">
-    <value>True</value>
-  </data>
-  <data name="chkValidateOnSave.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
-    <value>NoControl</value>
-  </data>
-  <data name="chkValidateOnSave.Location" type="System.Drawing.Point, System.Drawing">
-    <value>19, 19</value>
-  </data>
-  <data name="chkValidateOnSave.Size" type="System.Drawing.Size, System.Drawing">
-    <value>163, 17</value>
-  </data>
-  <data name="chkValidateOnSave.TabIndex" type="System.Int32, mscorlib">
-    <value>2</value>
-  </data>
-  <data name="chkValidateOnSave.Text" xml:space="preserve">
-    <value>Validate Resources On Save</value>
-  </data>
-  <data name="&gt;&gt;chkValidateOnSave.Name" xml:space="preserve">
-    <value>chkValidateOnSave</value>
-  </data>
-  <data name="&gt;&gt;chkValidateOnSave.Type" xml:space="preserve">
-    <value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </data>
-  <data name="&gt;&gt;chkValidateOnSave.Parent" xml:space="preserve">
-    <value>groupBox4</value>
-  </data>
-  <data name="&gt;&gt;chkValidateOnSave.ZOrder" xml:space="preserve">
     <value>0</value>
   </data>
-  <data name="groupBox4.Location" type="System.Drawing.Point, System.Drawing">
-    <value>16, 71</value>
-  </data>
-  <data name="groupBox4.Size" type="System.Drawing.Size, System.Drawing">
-    <value>426, 50</value>
-  </data>
-  <data name="groupBox4.TabIndex" type="System.Int32, mscorlib">
-    <value>9</value>
-  </data>
-  <data name="groupBox4.Text" xml:space="preserve">
-    <value>Editing</value>
-  </data>
-  <data name="&gt;&gt;groupBox4.Name" xml:space="preserve">
-    <value>groupBox4</value>
-  </data>
-  <data name="&gt;&gt;groupBox4.Type" xml:space="preserve">
-    <value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </data>
-  <data name="&gt;&gt;groupBox4.Parent" xml:space="preserve">
-    <value>$this</value>
-  </data>
-  <data name="&gt;&gt;groupBox4.ZOrder" xml:space="preserve">
-    <value>0</value>
-  </data>
   <metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>True</value>
   </metadata>

Modified: trunk/Tools/Maestro/Maestro.Editors/Generic/XmlEditorCtrl.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Editors/Generic/XmlEditorCtrl.cs	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/Maestro.Editors/Generic/XmlEditorCtrl.cs	2011-04-11 14:34:42 UTC (rev 5692)
@@ -263,18 +263,57 @@
 
         private void btnValidate_Click(object sender, EventArgs e)
         {
+            PerformValidation(false, false);
+        }
+
+        /// <summary>
+        /// Performs validation of the XML content
+        /// </summary>
+        /// <param name="silentSuccess">If true will not show a success dialog on successful validation</param>
+        /// <returns>true if validation was successful, false otherwise</returns>
+        public bool PerformValidation(bool silentSuccess, bool errorsOnly)
+        {
             if (this.Validator != null)
             {
-                string[] errors;
-                string[] warnings;
+                string[] errors = new string[0];
+                string[] warnings = new string[0];
 
-                this.Validator(out errors, out warnings);
+                try
+                {
+                    this.Validator(out errors, out warnings);
+                }
+                catch (XmlException ex)
+                {
+                    var err = new List<string>(errors);
+                    err.Add(ex.Message);
+                    errors = err.ToArray();
+                }
 
                 if (errors.Length > 0 || warnings.Length > 0)
-                    new XmlValidationResult(errors, warnings).Show();
+                {
+                    if (errorsOnly)
+                    {
+                        if (errors.Length > 0)
+                        {
+                            new XmlValidationResult(errors, new string[0]).Show();
+                            return false;
+                        }
+                        return true;
+                    }
+                    else
+                    {
+                        new XmlValidationResult(errors, warnings).Show();
+                    }
+                    return false;
+                }
                 else
-                    MessageBox.Show(Properties.Resources.XmlDocIsValid);
+                {
+                    if (!silentSuccess)
+                        MessageBox.Show(Properties.Resources.XmlDocIsValid);
+                    return true;
+                }
             }
+            return true;
         }
 
         private void btnFormat_Click(object sender, EventArgs e)

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/PlatformConnectionBase.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/PlatformConnectionBase.cs	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/PlatformConnectionBase.cs	2011-04-11 14:34:42 UTC (rev 5692)
@@ -53,7 +53,7 @@
 		/// <summary>
 		/// The current XML validator
 		/// </summary>
-		protected XMLValidator m_validator;
+		protected XmlValidator m_validator;
 
 		/// <summary>
 		/// The path of Xsd schemas 
@@ -78,7 +78,7 @@
             ResourceTypeRegistry.Init();
             
             m_serializers = new Hashtable();
-            m_validator = new XMLValidator();
+            m_validator = new XmlValidator();
             m_cachedSchemas = new Hashtable();
             m_schemasPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "Schemas");
 		}

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.Designer.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.Designer.cs	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.Designer.cs	2011-04-11 14:34:42 UTC (rev 5692)
@@ -1032,5 +1032,14 @@
                 return ResourceManager.GetString("WL_StartViewOutsideExtentsWarning", resourceCulture);
             }
         }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Line {0}, Char {1}: {2}.
+        /// </summary>
+        internal static string XmlValidationIssueTemplate {
+            get {
+                return ResourceManager.GetString("XmlValidationIssueTemplate", resourceCulture);
+            }
+        }
     }
 }

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.resx
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.resx	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Properties/Resources.resx	2011-04-11 14:34:42 UTC (rev 5692)
@@ -491,4 +491,7 @@
   <data name="ADF_MapWithIncompatibleCommericalCs" xml:space="preserve">
     <value>The Map Definition {0} has a coordinate system that is not EPSG:3857. This map is in a group containing one or more commerical base layers. The specified Map Definition may not correctly display or line up with the commerical base layers.</value>
   </data>
+  <data name="XmlValidationIssueTemplate" xml:space="preserve">
+    <value>Line {0}, Char {1}: {2}</value>
+  </data>
 </root>
\ No newline at end of file

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ValidationResultSet.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ValidationResultSet.cs	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Resource/Validation/ValidationResultSet.cs	2011-04-11 14:34:42 UTC (rev 5692)
@@ -108,6 +108,25 @@
         }
 
         /// <summary>
+        /// Gets all issues filtered by the specified validation status types
+        /// </summary>
+        /// <param name="statTypes"></param>
+        /// <returns></returns>
+        public ValidationIssue[] GetAllIssues(params ValidationStatus[] statTypes)
+        {
+            var issues = new List<ValidationIssue>();
+            foreach (string resId in _issues.Keys)
+            {
+                foreach (var issue in _issues[resId].Keys)
+                {
+                    if (Array.IndexOf(statTypes, issue.Status) >= 0)
+                        issues.Add(issue);
+                }
+            }
+            return issues.ToArray();
+        }
+
+        /// <summary>
         /// Adds the issue.
         /// </summary>
         /// <param name="issue">The issue.</param>

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/XmlValidator.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/XmlValidator.cs	2011-04-11 09:58:59 UTC (rev 5691)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/XmlValidator.cs	2011-04-11 14:34:42 UTC (rev 5692)
@@ -28,29 +28,26 @@
 	using System.Xml;
 	using System.Xml.Schema;
 	using System.Text;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
 
 	///<summary>
 	/// Class that makes XSD validation
 	///</summary>
-	public class XMLValidator
+	public class XmlValidator
 	{
-		// Validation Error Count
-		private int ErrorsCount = 0;
+        private List<string> warnings = new List<string>();
+        private List<string> errors = new List<string>();
 
-		// Validation Error Message
-		private string ErrorMessage = "";
+        public ReadOnlyCollection<string> ValidationWarnings
+        {
+            get { return this.warnings.AsReadOnly(); }
+        }
 
-        /// <summary>
-        /// Default validation handler method
-        /// </summary>
-        /// <param name="sender">The sender.</param>
-        /// <param name="args">The <see cref="System.Xml.Schema.ValidationEventArgs"/> instance containing the event data.</param>
-		public void ValidationHandler(object sender,
-			ValidationEventArgs args)
-		{
-			ErrorMessage = ErrorMessage + args.Message + "\r\n";
-			ErrorsCount ++;
-		}
+        public ReadOnlyCollection<string> ValidationErrors
+        {
+            get { return this.errors.AsReadOnly(); }
+        }
 
         /// <summary>
         /// Validates the specified XML.
@@ -59,20 +56,34 @@
         /// <param name="xsd">The XSD.</param>
 		public void Validate(System.IO.Stream xml, XmlSchema xsd)
 		{
-			// Declare local objects
-			XmlValidatingReader vr = new XmlValidatingReader( xml, XmlNodeType.Document, null);
-			vr.Schemas.Add(xsd);
+            this.warnings.Clear();
+            this.errors.Clear();
 
-			// Add validation event handler
-			vr.ValidationType = ValidationType.Schema;
-			vr.ValidationEventHandler += new ValidationEventHandler(ValidationHandler);
+            var config = new XmlReaderSettings();
+            if (xsd != null)
+                config.Schemas.Add(xsd);
+            config.ValidationType = ValidationType.Schema;
+            config.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
+            config.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
+            config.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
+            //This will trap all the errors and warnings that are raised
+            config.ValidationEventHandler += (s, e) =>
+            {
+                var ex = e.Exception;
+                if (e.Severity == XmlSeverityType.Warning)
+                {
+                    this.warnings.Add(string.Format(Properties.Resources.XmlValidationIssueTemplate, ex.LineNumber, ex.LinePosition, ex.Message));
+                }
+                else
+                {
+                    this.errors.Add(string.Format(Properties.Resources.XmlValidationIssueTemplate, ex.LineNumber, ex.LinePosition, ex.Message));
+                }
+            };
 
-			// Validate XML data
-			while(vr.Read());
-
-			// Raise exception, if XML validation fails
-			if (ErrorsCount > 0)
-				throw new Exception(ErrorMessage);
+            using (var reader = XmlReader.Create(xml, config))
+            {
+                while (reader.Read()) { } //Trigger the validation
+            }
 		}
 	}
 }



More information about the mapguide-commits mailing list