Free Information Technology Magazines and eBooks

Friday, October 16, 2009

Validate XML Fragment Against Schema in VB.NET

On my previous project which involves XML processing, I used the code I posted here to validate XML file against its schema (.xsd). I tried to reuse the same code on my newest XML project but unfortunately it doesn't fit the requirements. What I want is to check out ALL of errors from the XML, rather than stopping on the first one. The code should display each error on every XML (fragment) element and don't stop until it reach the end of the file. Luckily for me, I found this VB.NET class that do exactly what I want.


Here is the code of the XMLValidator class.


Imports System.Collections.Generic
Imports System.IO
Imports System.Xml
Imports System.Xml.Schema

Public Class XmlValidator

Private ErrorList As List(Of String)
Private SchemaList As List(Of String)
Private SchemaReaderSettings As XmlReaderSettings
Private SchemaValidation As ValidationEventHandler

Public Sub New()
SchemaList = New List(Of String)
SchemaReaderSettings = New XmlReaderSettings()
SchemaValidation = New ValidationEventHandler(AddressOf ValidationHandler)
End Sub

Public ReadOnly Property SchemaSettings() As XmlReaderSettings
Get
Return SchemaReaderSettings
End Get
End Property

Public ReadOnly Property Schemas() As List(Of String)
Get
Return SchemaList
End Get
End Property

'''
''' Validates the given XML string against the schema(s)
'''

''' The raw XML data to validate
''' A generic list of error messages
Public Function ValidateXml(ByVal RawXml As String) As List(Of String)
ErrorList = New List(Of String)

If Me.Schemas.Count > 0 Then
Dim ReaderSettings As New XmlReaderSettings()

With ReaderSettings
.ValidationType = ValidationType.Schema
.ValidationFlags = XmlSchemaValidationFlags.ProcessSchemaLocation Or XmlSchemaValidationFlags.ReportValidationWarnings Or XmlSchemaValidationFlags.AllowXmlAttributes

For Each SchemaPath As String In Me.Schemas
.Schemas.Add(Nothing, XmlReader.Create(SchemaPath, Me.SchemaSettings))
Next

AddHandler .ValidationEventHandler, SchemaValidation
End With

Using Reader As XmlReader = XmlReader.Create(New StringReader(RawXml), ReaderSettings)
While Reader.Read()
' Reads the whole file and will call the validation
' handler subroutine if an error is detected. Doing
' it this way allows us to pick out ALL of the errors
' from the XML, rather than bombing out on the first
' one.
End While
End Using
End If

Return ErrorList
End Function

Private Sub ValidationHandler(ByVal sender As Object, ByVal e As System.Xml.Schema.ValidationEventArgs)
If e.Severity = XmlSeverityType.Error Then
ErrorList.Add(e.Message)
End If
End Sub
End Class



Here is how you can call the class on your VB.NET project.


Private Sub btnValidate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnValidate.Click
Dim Validator As New XmlValidator()
Dim Errors As List(Of String)
Dim RawXml As String

Using Reader As New StreamReader("test.xml", Encoding.UTF8)
RawXml = Reader.ReadToEnd()
End Using

With Validator
.SchemaSettings.ProhibitDtd = False
.Schemas.Add("schema1.xsd")
Errors = .ValidateXml(RawXml)
End With

For Each Err As String In Errors
Console.WriteLine(Err)
Next

End Sub



You can also download the complete VB project sourcode here.

For more coding tips & tricks, subscribe now.

0 comments: