Click here to Skip to main content
15,881,757 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi folks,

I'm new here so please don't beat me up yet.

To setup my question, here's my scenario; I'm writing an application that dynamically adds controls to a Winform. How it is done is via an SQL database. I have a table that contains 2 text column -- a column for a "question", and another column for the type of input required for the answer (e.g. TextBox, NumericUpDown, DataGridView, etc.), and another column for "ControlSource" which may contain various things.

When the control is a DataGridView, the "ControlSource" column will generally contain an XML Schema, like this;

<?xml version="1.0" encoding="UTF-8" ?>

<!-- U.S. State Abbreviations Type -->
<xsd:simpleType name="StateType">
   <xsd:restriction base="xsd:string">
      <xsd:enumeration value="AK"/>
      <xsd:enumeration value="AL"/>
      <xsd:enumeration value="AR"/>
      <xsd:enumeration value="AZ"/>
      <xsd:enumeration value="CA"/>
      <xsd:enumeration value="CO"/>
      <xsd:enumeration value="CT"/>
      <xsd:enumeration value="DC"/>
      <xsd:enumeration value="DE"/>
      <xsd:enumeration value="FL"/>
      <xsd:enumeration value="GA"/>
      <xsd:enumeration value="HI"/>
      <xsd:enumeration value="IA"/>
      <xsd:enumeration value="ID"/>
      <xsd:enumeration value="IL"/>
      <xsd:enumeration value="IN"/>
      <xsd:enumeration value="KS"/>
      <xsd:enumeration value="KY"/>
      <xsd:enumeration value="LA"/>
      <xsd:enumeration value="MA"/>
      <xsd:enumeration value="MD"/>
      <xsd:enumeration value="ME"/>
      <xsd:enumeration value="MI"/>
      <xsd:enumeration value="MN"/>
      <xsd:enumeration value="MO"/>
      <xsd:enumeration value="MS"/>
      <xsd:enumeration value="MT"/>
      <xsd:enumeration value="NC"/>
      <xsd:enumeration value="ND"/>
      <xsd:enumeration value="NE"/>
      <xsd:enumeration value="NH"/>
      <xsd:enumeration value="NJ"/>
      <xsd:enumeration value="NM"/>
      <xsd:enumeration value="NV"/>
      <xsd:enumeration value="NY"/>
      <xsd:enumeration value="OH"/>
      <xsd:enumeration value="OK"/>
      <xsd:enumeration value="OR"/>
      <xsd:enumeration value="PA"/>
      <xsd:enumeration value="RI"/>
      <xsd:enumeration value="SC"/>
      <xsd:enumeration value="SD"/>
      <xsd:enumeration value="TN"/>
      <xsd:enumeration value="TX"/>
      <xsd:enumeration value="UT"/>
      <xsd:enumeration value="VA"/>
      <xsd:enumeration value="VT"/>
      <xsd:enumeration value="WA"/>
      <xsd:enumeration value="WI"/>
      <xsd:enumeration value="WV"/>
      <xsd:enumeration value="WY"/>

<!-- definition of complex elements -->
<xsd:element name="DataItems">
      <xsd:element name="Name" type="xsd:string"/>
      <xsd:element name="Address" type="xsd:string"/>
      <xsd:element name="City" type="xsd:string"/>
      <xsd:element name="State" type="StateType"/>
      <xsd:element name="Zip" type="xsd:string"/>
      <xsd:element name="DOB" type="xsd:date"/>

Now here's the main problem -- The DataTable that's bound to the DataGridview will only validate base data types (string, integer, float, decimal, bit, etc.), and I’m needing to place restrictions, via an XML schema, on what a user can enter.

For example, referencing the XML Schema above, if I have a “State” column in the datatable/grid, users should only be able to enter “AK”, AZ”, “CA, “TX” and so on, but the datatable will not validate it (throw an error) if I enter “ZZZ” in the State column.

I'm thinking I need to read the XML back from the DataTable, create an XmlDocument, add the schema to it, and validate the document rather than the DataTable. Both the XML Schema and the XML data that the user have entered are available as strings (the file system is not used). Does this seem like the best approach? Here's what I have so far;

' **** BEGIN: Test Validation **** '
Dim objSettings As New System.Xml.XmlReaderSettings()
objSettings.CheckCharacters = True
objSettings.CloseInput = True
objSettings.ConformanceLevel = System.Xml.ConformanceLevel.Auto
objSettings.DtdProcessing = System.Xml.DtdProcessing.Ignore
objSettings.ValidationFlags = System.Xml.Schema.XmlSchemaValidationFlags.ProcessInlineSchema Or System.Xml.Schema.XmlSchemaValidationFlags.ReportValidationWarnings Or System.Xml.Schema.XmlSchemaValidationFlags.AllowXmlAttributes Or System.Xml.Schema.XmlSchemaValidationFlags.ProcessIdentityConstraints
        objSettings.ValidationType = System.Xml.ValidationType.Schema

' Get a pointer to the grid's table datasource
Dim tblData As System.Data.DataTable = DirectCast(objCtrl.DataSource, System.Data.DataTable)

' Get a pointer to the table's DataSet
Dim rstData As System.Data.DataSet = tblData.DataSet

' Read the schema from the DataSet
Dim strXMLSchema As String = rstData.GetXmlSchema()

' Read the xml from the DataSet
Dim strXMLData As String = rstData.GetXml()

' Create an XmlReader object
Dim rdrXmlReader As System.Xml.XmlReader = System.Xml.XmlReader.Create(New System.IO.StringReader(strXMLSchema), objSettings)

' Create an XmlReader document object
Dim document As New System.Xml.XmlDocument()

' Schema?  Not sure this is right... 
Dim schemas As New System.Xml.Schema.XmlSchemaSet()
schemas.Add("", System.Xml.XmlReader.Create(rdrXmlReader, objSettings))

Dim eventHandler As New System.Xml.Schema.ValidationEventHandler(AddressOf ValidationEventHandler)

' **** END: Test Validation **** '

For completeness, here's the (very simple for now) ValidationEventHandler routine;

Shared Sub ValidationEventHandler(ByVal sender As Object, ByVal e As System.Xml.Schema.ValidationEventArgs)

   Select Case e.Severity
      Case System.Xml.Schema.XmlSeverityType.Error
         Console.WriteLine("Error: {0}", e.Message)
      Case System.Xml.Schema.XmlSeverityType.Warning
         Console.WriteLine("Warning {0}", e.Message)
   End Select
End Sub

The call to "document.Validate(eventHandler)" that's commented out is where I'm hitting problem, which is it does not correctly validate against the schema because it allows things other than one of the enumerated "StateType" values. And the validationEventHandler is definitely being called, but nothing is happening.

Any suggestions?

Thanks in advance.
Updated 18-Dec-13 6:02am

1 solution

If i'm not wrong... *.xsd file has been never loaded before validation is called.

Have a look here:
XML Schema (XSD) Validation with XmlSchemaSet[^]
Extensions.Validate Method (XDocument, XmlSchemaSet, ValidationEventHandler)[^]
Share this answer
T38Jett 18-Dec-13 13:22pm    
Thank you Maciej, but I believe that's where I got the examples for the code I already have.

The problem may be that the "" I'm adding does not contain the rules/restrictions. Thinking along those lines, I also forgot to mention that I have a schema file I would like to use, but it's on the local hard drive, and I'm not sure how to add it using the "schemas.Add()" method.

Do you know how to accomplish that? Do you have an example of using the "schemas.Add()" method to add a schema file from the local hard drive?

Otherwise, the file system is not used, not at all. Everything is stored in an SQL database... the original schema (columns and data types), and even the XML from the dataset is stored in an XML column in SQL.
Maciej Los 18-Dec-13 15:16pm    
Follow the first link. There is an example how to use Schemas.Add() method.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900