[ad_1]
こんにちは皆さん。
私はここに来たばかりなので、まだ私を殴らないでください。
質問を設定するために、これが私のシナリオです。 Winform にコントロールを動的に追加するアプリケーションを作成しています。 これは SQL データベースを介して行われます。 2 つのテキスト列を含むテーブルがあります。1 つは「質問」の列、もう 1 つは回答に必要な入力の種類 (TextBox、NumericUpDown、DataGridView など) の列、もう 1 つは「ControlSource」の列です。さまざまなものが含まれる可能性があります。
コントロールが DataGridView の場合、通常、「ControlSource」列には次のような XML スキーマが含まれます。
<?xml version="1.0" encoding="UTF-8" ?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <!-- 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"/> </xsd:restriction> </xsd:simpleType> <!-- definition of complex elements --> <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>
ここで主な問題が発生します。DataGridview にバインドされている DataTable は基本データ型 (文字列、整数、浮動小数点、小数、ビットなど) のみを検証するため、XML スキーマを介して制限を設ける必要があります。ユーザーが入力できるもの。
たとえば、上記の XML スキーマを参照すると、データテーブル/グリッドに「State」列がある場合、ユーザーは「AK」、「AZ」、「CA」、「TX」などのみを入力できるはずですが、データテーブル「State」列に「ZZZ」と入力すると、検証されません (エラーがスローされます)。
DataTable から XML を読み取り、XmlDocument を作成し、それにスキーマを追加して、DataTable ではなくドキュメントを検証する必要があると考えています。 XML スキーマとユーザーが入力した XML データはどちらも文字列として利用できます (ファイル システムは使用されません)。 これが最善のアプローチだと思われますか? 私がこれまでに持っているものは次のとおりです。
' **** 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() document.LoadXml(strXMLData) ' Schema? Not sure this is right... 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) ' **** END: Test Validation **** '
完全を期すために、(今のところ非常に単純な) ValidationEventHandler ルーチンを次に示します。
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
コメントアウトされている「document.Validate(eventHandler)」の呼び出しで問題が発生します。列挙された「StateType」値の 1 つ以外のものを許可するため、スキーマに対して正しく検証されません。 そして、 validationEventHandler は確実に呼び出されていますが、何も起こりません。
助言がありますか?
前もって感謝します。
解決策 1
私が間違っていなければ… *.xsd ファイルは、検証が呼び出される前にロードされていません。
ここを見てください:
XmlSchemaSet を使用した XML スキーマ (XSD) 検証[^]
Extensions.Validate メソッド (XDocument、XmlSchemaSet、ValidationEventHandler)[^]
[ad_2]
コメント