我需要针对 xsd 验证 sql server 中的 xml。xsd 太复杂,无法与 XML SCHEMA COLLECTION 一起使用,所以我正在编写一个 SQL CLR 函数来完成它。我对如何“不得不”编写代码有两个问题。代码是针对 2.0 的 VB.NET,顺便说一句,尽管我认为我在 C# 中遇到了同样的问题。如果不乐意切换。
[1] 我似乎无法将设置附加到由 SqlXml.CreateReader 创建的阅读器,因此我必须加载到 XmlDocument 中才能执行验证。我也不能直接将 SqlXml 加载到 XmlDocument 中——我必须进行额外的类型转换。
我错过了什么,还是就是这样?
[2] 我讨厌我使用共享成员从事件处理程序传递验证结果,然后返回给调用者。这在我的第一个特定用法中很好,我知道有一系列单独的调用。但是,如果我曾经尝试将它与多个调用者一起使用或在集合操作中使用,我担心结果会令人怀疑。
有没有解决的办法?
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
Imports System.Xml
Imports System.Xml.Schema
Partial Public Class UserDefinedFunctions
'this is from an ms sample
Const TARGET_NAMESPACE As String = "http://www.contoso.com/books"
Const SCHEMA_URI As String = "D:\temp\temp.xsd"
Shared schemaSet As XmlSchemaSet
Shared schemaValidationEventHandler As ValidationEventHandler
Shared isValid As Boolean
Shared doc As XmlDocument
Shared Sub New()
schemaSet = New XmlSchemaSet
schemaSet.Add(TARGET_NAMESPACE, SCHEMA_URI)
schemaSet.Compile()
doc = New XmlDocument
doc.Schemas = schemaSet
schemaValidationEventHandler = New ValidationEventHandler(
AddressOf ValidationCallBack)
End Sub
<SqlFunction()> _
Public Shared Function ValidateWithContosoXsd(ByVal xml As SqlXml) _
As SqlBoolean
isValid = True
Dim reader As XmlReader = xml.CreateReader
reader.Settings.ValidationType = ValidationType.Schema
doc.Load(reader)
doc.Validate(schemaValidationEventHandler)
ValidateWithContosoXsd = isValid
End Function
Private Shared Sub ValidationCallBack(ByVal sender As Object,
ByVal args As ValidationEventArgs)
isValid = False
End Sub
End Class
我确实遵循了一条线索,尝试使用初始阅读器作为第二个阅读器的基础,该阅读器在大致等效的控制台应用程序中工作。控制台应用程序的不同之处在于,第一个准备就绪是来自文件 uri 而不是来自 SqlXml。可悲的是,这在 clr 中完成时总是显示有效。
Partial Public Class UserDefinedFunctions
Const TARGET_NAMESPACE As String = "http://www.contoso.com/books"
Const SCHEMA_URI As String = "D:\temp\temp.xsd"
Shared settings As XmlReaderSettings
Shared schemaSet As XmlSchemaSet
Shared schemaValidationEventHandler As ValidationEventHandler
Shared isValid As Boolean
Shared Sub New()
schemaSet = New XmlSchemaSet
schemaSet.Add(TARGET_NAMESPACE, SCHEMA_URI)
schemaSet.Compile()
schemaValidationEventHandler = New ValidationEventHandler(AddressOf ValidationCallBack)
settings = New XmlReaderSettings
settings.Schemas = schemaSet
settings.ValidationType = ValidationType.Schema
AddHandler settings.ValidationEventHandler, schemaValidationEventHandler
End Sub
<SqlFunction()> _
Public Shared Function ValidateWithContosoXsd(ByVal xml As SqlXml) As SqlBoolean
isValid = True
Dim baseReader As XmlReader = xml.CreateReader
Dim reader As XmlReader = XmlReader.Create(baseReader, settings)
While reader.Read()
End While
ValidateWithContosoXsd = isValid
End Function
Private Shared Sub ValidationCallBack(ByVal sender As Object, ByVal args As ValidationEventArgs)
isValid = False
End Sub
End Class