针对模式验证XML的问题 - 异常方法 [英] Problems Validating XML Against Schema - Unusual Approach

查看:70
本文介绍了针对模式验证XML的问题 - 异常方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨伙计们,



我是新来的,所以请不要打扰我。



要设置我的问题,这是我的方案;我正在编写一个动态添加控件到Winform的应用程序。它是如何通过SQL数据库完成的。我有一个表包含2个文本列 - 一个用于问题的列,另一个列用于答案所需的输入类型(例如TextBox,NumericUpDown,DataGridView等),另一列用于ControlSource可能包含各种东西。



当控件是DataGridView时,ControlSource列通常包含一个XML Schema,就像这样;



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" ?>
<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 Schema,如果我在数据表/网格中有一个State列,用户应该只能输入AK, AZ,CA,TX等,但如果我在State列中输入ZZZ,则数据表不会验证它(抛出错误)。



我想我需要从DataTable读取XML,创建一个XmlDocument,向其添加模式,并验证文档而不是DataTable。 XML Schema和用户输入的XML数据都以字符串形式提供(不使用文件系统)。这看起来像是最好的方法吗?这是我到目前为止所拥有的;





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()
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例程;





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





被注释掉的document.Validate(eventHandler)调用是我遇到问题的地方,它没有正确验证对于模式,因为它允许除了枚举的StateType值之外的其他内容。而且肯定会调用validationEventHandler,但什么也没发生。



有什么建议吗?



提前谢谢。



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.

推荐答案

如果我没错... * .xsd文件在调用验证之前从未加载。



看看这里:

使用XmlSchemaSet进行XML模式(XSD)验证 [ ^ ]

Extensions.Validate Method (XDocument, XmlSchemaSet, ValidationEventHandler)[^]
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)[^]

< br/>

这篇关于针对模式验证XML的问题 - 异常方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆