Powershell v2 v3 Function Validate Schema

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# .NET
As 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 delegates
After 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 1
                  Validate-Schema -XmlFilePath C:PowerShell and XMLproduct.xml -SchemaType DTD
                 
                  This 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 XmlFilePath
                  A mandatory parameter indicating the path to the .xml file.
                 
            .PARAMETER SchemaType
                  A mandatory parameter indicating whether the validation type is DTD or XSD. Default is XSD.
                 
            .OUTPUTS
                  Boolean.
                 
                  If you add the -Verbose switch the function will add comments indicating more specifically the item throwing the error during validation.
           
            .NOTES
                  Author: Will Steele (will.steele@live.com)
                  Date last modified: 2012/08/20
                  By 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 file
      while($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";

Related Posts by Categories

0 comments:

Post a Comment