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;
="1.0"="UTF-8"
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<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"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="DataItems">
<xsd:complexType>
<xsd:sequence>
<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"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
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;
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
Dim tblData As System.Data.DataTable = DirectCast(objCtrl.DataSource, System.Data.DataTable)
Dim rstData As System.Data.DataSet = tblData.DataSet
Dim strXMLSchema As String = rstData.GetXmlSchema()
Dim strXMLData As String = rstData.GetXml()
Dim rdrXmlReader As System.Xml.XmlReader = System.Xml.XmlReader.Create(New System.IO.StringReader(strXMLSchema), objSettings)
Dim document As New System.Xml.XmlDocument()
document.LoadXml(strXMLData)
Dim schemas As New System.Xml.Schema.XmlSchemaSet()
schemas.Add("http://www.w3.org/2001/XMLSchema", System.Xml.XmlReader.Create(rdrXmlReader, objSettings))
Dim eventHandler As New System.Xml.Schema.ValidationEventHandler(AddressOf ValidationEventHandler)
document.Validate(eventHandler)
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.