xsdに対してSQLサーバーでxmlを検証する必要があります。xsd は複雑すぎて XML SCHEMA COLLECTION で使用できないため、それを行う SQL CLR 関数を作成しています。コードを書く必要があった方法には 2 つの問題があります。コードは 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
手がかりに従って、最初のリーダーを 2 番目のリーダーの基礎として使用してみました。これは、ほぼ同等のコンソール アプリで動作します。コンソール アプリの違いは、最初の準備が SqlXml ではなくファイル uri から行われることです。悲しいことに、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