This function stems from more work on my PowerShell and XML book. I had pieced together a large portion of this function from the following Microsoft knowledge base article,
How To Validate an XML Document by Using DTD, XDR, or XSD in Visual C# .NETAs I worked further on it I ran into problems with the delegate so I read through some of Oisins posts on the topic, particularly this one:
PowerShell 2.0 RC: Working with .NET Callbacks Part 1 - Synchronous
Still unable to figure it out I posted on the PowerShell.org forums under the Advanced Scripting section,
Looking for the PowerShell way to write/add delegatesAfter some back and forth with Kirk, he finally got me in the ballpark and helped me find one of the few uses of Write-Host (delegates suppress Write-Output, so, you have to use another pipeline to get output from a delegate back to the host). Once I had a working script, I converted it into the following function:
function Validate-Schema{<#.EXAMPLE 1Validate-Schema -XmlFilePath C:PowerShell and XMLproduct.xml -SchemaType DTDThis example illustrates how to validate a DTD schema referenced directly from within the .xml file itself. This example includes an intentional error and outputs the following:Error: The required attribute ProductID is missing.Document is invalid.PARAMETER XmlFilePathA mandatory parameter indicating the path to the .xml file..PARAMETER SchemaTypeA mandatory parameter indicating whether the validation type is DTD or XSD. Default is XSD..OUTPUTSBoolean.If you add the -Verbose switch the function will add comments indicating more specifically the item throwing the error during validation..NOTESAuthor: Will Steele (will.steele@live.com)Date last modified: 2012/08/20By default this script will validate against XSD and will only return a boolean value. If you want more verbose output add the -Verbose switch to the function when its called.#>[CmdletBinding()]param([Parameter(Mandatory = $true,Position = 0)][ValidateNotNullOrEmpty()]$XmlFilePath,[Parameter(Mandatory = $true,Position = 1)][ValidateNotNullOrEmpty()][ValidateSet(DTD,XSD)]$SchemaType = XSD)# Create delegate for handling/reporting errors[System.Xml.Schema.ValidationEventHandler] $onValidationError = {param($sender,$eventArgs)$isValid = $false;Write-Verbose "Error: $($eventArgs.Message)";}# Set while loop flag$isValid = $true;# Instantiate XML text reader$XmlTextReader = New-Object -TypeName System.Xml.XmlTextReader($XmlFilePath)# Instantiate ValidatingReader and set ValidationType$XmlValidatingReader = New-Object -TypeName System.Xml.XmlValidatingReader($XmlTextReader)switch($SchemaType){DTD{$XmlValidatingReader.ValidationType = [System.Xml.ValidationType]::DTD;}XSD{$XmlValidatingReader.ValidationType = [System.Xml.ValidationType]::Schema;}}# Add handler to Validating Reader$XmlValidatingReader.add_ValidationEventHandler($onValidationError)# Validate filewhile($XmlValidatingReader.Read()) {}# Close handles$XmlValidatingReader.Close()$XmlTextReader.Close()# Output whether the document is valid or invalid.if ($isValid){Write-Verbose "Document is valid";$isValid}else{Write-Verbose "Document is invalid";