How do I use PowerShell to Validate XML files against an XSD?

前端 未结 8 1897
小鲜肉
小鲜肉 2020-12-05 02:26

As a part of my development I\'d like to be able to validate an entire folder\'s worth of XML files against a single XSD file. A PowerShell function seems like a good candid

8条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-05 03:16

    I realise this is an old question however I tried the answers provided and could not get them to work successfully in Powershell.

    I have created the following function which uses some of the techniques described here. I have found it very reliable.

    I had to validate XML documents before at various times however I always found the line number to be 0. It appears the XmlSchemaException.LineNumber will only be available while loading the document.

    If you do validation afterwards using the Validate() method on an XmlDocument then LineNumber/LinePosition will always be 0.

    Instead you should do validation while reading using an XmlReader and adding a validation event handler to a block of script.

    Function Test-Xml()
    {
        [CmdletBinding(PositionalBinding=$false)]
        param (
        [Parameter(ValueFromPipeline=$true, Mandatory=$true)]
            [string] [ValidateScript({Test-Path -Path $_})] $Path,
    
            [Parameter(Mandatory=$true)]
            [string] [ValidateScript({Test-Path -Path $_})] $SchemaFilePath,
    
            [Parameter(Mandatory=$false)]
            $Namespace = $null
        )
    
        [string[]]$Script:XmlValidationErrorLog = @()
        [scriptblock] $ValidationEventHandler = {
            $Script:XmlValidationErrorLog += "`n" + "Line: $($_.Exception.LineNumber) Offset: $($_.Exception.LinePosition) - $($_.Message)"
        }
    
        $readerSettings = New-Object -TypeName System.Xml.XmlReaderSettings
        $readerSettings.ValidationType = [System.Xml.ValidationType]::Schema
        $readerSettings.ValidationFlags = [System.Xml.Schema.XmlSchemaValidationFlags]::ProcessIdentityConstraints -bor
                [System.Xml.Schema.XmlSchemaValidationFlags]::ProcessSchemaLocation -bor 
                [System.Xml.Schema.XmlSchemaValidationFlags]::ReportValidationWarnings
        $readerSettings.Schemas.Add($Namespace, $SchemaFilePath) | Out-Null
        $readerSettings.add_ValidationEventHandler($ValidationEventHandler)
        try 
        {
            $reader = [System.Xml.XmlReader]::Create($Path, $readerSettings)
            while ($reader.Read()) { }
        }
    
        #handler to ensure we always close the reader sicne it locks files
        finally 
        {
            $reader.Close()
        }
    
        if ($Script:XmlValidationErrorLog) 
        {
            [string[]]$ValidationErrors = $Script:XmlValidationErrorLog
            Write-Warning "Xml file ""$Path"" is NOT valid according to schema ""$SchemaFilePath"""
            Write-Warning "$($Script:XmlValidationErrorLog.Count) errors found"
        }
        else 
        {
            Write-Host "Xml file ""$Path"" is valid according to schema ""$SchemaFilePath"""
        }
    
        Return ,$ValidationErrors #The comma prevents powershell from unravelling the collection http://bit.ly/1fcZovr
    }
    

提交回复
热议问题