Skip to main content
added 288 characters in body
Source Link
wangzq
  • 926
  • 8
  • 17
function Test-XmlFile
{
    <#
    .Synopsis
        Validates an xml file against an xml schema file.
    .Example
        PS> dir *.xml | Test-XmlFile schema.xsd
    #>
    [CmdletBinding()]
    param (     
        [Parameter(ValueFromPipeline=$true, Mandatory=$true)]
        [string] $XmlFile$SchemaFile,

        [Parameter(ValueFromPipeline=$true, Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
        [alias('Fullname')]
        [string] $SchemaFile$XmlFile,

        [scriptblock] $ValidationEventHandler = { Write-Error $args[1].Exception }
    )

$xml = New-Object System.Xml.XmlDocument begin {
        $schemaReader = New-Object System.Xml.XmlTextReader $SchemaFile
        $schema = [System.Xml.Schema.XmlSchema]::Read($schemaReader, $ValidationEventHandler)
    }

    process {
        $ret = $true
        try {
            $xml = New-Object System.Xml.XmlDocument
            $xml.Schemas.Add($schema) | Out-Null
            $xml.Load($XmlFile)
            $xml.Validate($ValidationEventHandler){

PS C:\temp\lab-xml-validation> .\Test-Xml.ps1 test.xml test.xsd

System.Xml.Schema.XmlSchemaValidationException: The element 'address' has invalid child element 'name'.            throw ([PsCustomObject] @{
At C:\temp\lab-xml-validation\Test-Xml.ps1:8 char:42                      SchemaFile = $SchemaFile
+     [scriptblock] $ValidationEventHandler                  XmlFile = {$XmlFile
 Write-Error                       Exception = $args[1].Exception
                    })
+                })
        } catch {
            Write-Error $_
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~      $ret = $false
    + CategoryInfo   }
       : NotSpecified:$ret
    }

    end {
        $schemaReader.Close(:) 
 [Write-Error], WriteErrorException  }
}

PS C:\temp\lab-xml-validation> dir test.xml | Test-XmlFile test.xsd

System.Xml.Schema.XmlSchemaValidationException: The element 'address' +has FullyQualifiedErrorIdinvalid :child Microsoftelement 'name'.PowerShell 
.Commands.WriteErrorException.
param (     
[Parameter(ValueFromPipeline=$true, Mandatory=$true)]
    [string] $XmlFile,

    [Parameter(Mandatory=$true)]
    [string] $SchemaFile,

    [scriptblock] $ValidationEventHandler = { Write-Error $args[1].Exception }
)

$xml = New-Object System.Xml.XmlDocument
$schemaReader = New-Object System.Xml.XmlTextReader $SchemaFile
$schema = [System.Xml.Schema.XmlSchema]::Read($schemaReader, $ValidationEventHandler)
$xml.Schemas.Add($schema) | Out-Null
$xml.Load($XmlFile)
$xml.Validate($ValidationEventHandler)

PS C:\temp\lab-xml-validation> .\Test-Xml.ps1 test.xml test.xsd

System.Xml.Schema.XmlSchemaValidationException: The element 'address' has invalid child element 'name'.
At C:\temp\lab-xml-validation\Test-Xml.ps1:8 char:42
+     [scriptblock] $ValidationEventHandler = { Write-Error $args[1].Exception }
+                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException
function Test-XmlFile
{
    <#
    .Synopsis
        Validates an xml file against an xml schema file.
    .Example
        PS> dir *.xml | Test-XmlFile schema.xsd
    #>
    [CmdletBinding()]
    param (     
        [Parameter(Mandatory=$true)]
        [string] $SchemaFile,

        [Parameter(ValueFromPipeline=$true, Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
        [alias('Fullname')]
        [string] $XmlFile,

        [scriptblock] $ValidationEventHandler = { Write-Error $args[1].Exception }
    )

    begin {
        $schemaReader = New-Object System.Xml.XmlTextReader $SchemaFile
        $schema = [System.Xml.Schema.XmlSchema]::Read($schemaReader, $ValidationEventHandler)
    }

    process {
        $ret = $true
        try {
            $xml = New-Object System.Xml.XmlDocument
            $xml.Schemas.Add($schema) | Out-Null
            $xml.Load($XmlFile)
            $xml.Validate({
                    throw ([PsCustomObject] @{
                        SchemaFile = $SchemaFile
                        XmlFile = $XmlFile
                        Exception = $args[1].Exception
                    })
                })
        } catch {
            Write-Error $_
            $ret = $false
        }
        $ret
    }

    end {
        $schemaReader.Close() 
    }
}

PS C:\temp\lab-xml-validation> dir test.xml | Test-XmlFile test.xsd

System.Xml.Schema.XmlSchemaValidationException: The element 'address' has invalid child element 'name'. 
...
Source Link
wangzq
  • 926
  • 8
  • 17

I want to comment that the script in current accepted answer doesn't validate errors about incorrect orders of elements of xs:sequence. For example: test.xml

<addresses xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation='test.xsd'>
  <address>
    <street>Baker street 5</street>
    <name>Joe Tester</name>
  </address>
</addresses>

test.xsd

<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>    
<xs:element name="addresses">
      <xs:complexType>
       <xs:sequence>
         <xs:element ref="address" minOccurs='1' maxOccurs='unbounded'/>
       </xs:sequence>
     </xs:complexType>
    </xs:element>
    
     <xs:element name="address">
      <xs:complexType>
       <xs:sequence>
         <xs:element ref="name" minOccurs='0' maxOccurs='1'/>
         <xs:element ref="street" minOccurs='0' maxOccurs='1'/>
       </xs:sequence>
      </xs:complexType>
     </xs:element>
    
     <xs:element name="name" type='xs:string'/>
     <xs:element name="street" type='xs:string'/>
    </xs:schema>

I wrote another version that can report this error:

param (     
[Parameter(ValueFromPipeline=$true, Mandatory=$true)]
    [string] $XmlFile,

    [Parameter(Mandatory=$true)]
    [string] $SchemaFile,

    [scriptblock] $ValidationEventHandler = { Write-Error $args[1].Exception }
)

$xml = New-Object System.Xml.XmlDocument
$schemaReader = New-Object System.Xml.XmlTextReader $SchemaFile
$schema = [System.Xml.Schema.XmlSchema]::Read($schemaReader, $ValidationEventHandler)
$xml.Schemas.Add($schema) | Out-Null
$xml.Load($XmlFile)
$xml.Validate($ValidationEventHandler)

PS C:\temp\lab-xml-validation> .\Test-Xml.ps1 test.xml test.xsd

System.Xml.Schema.XmlSchemaValidationException: The element 'address' has invalid child element 'name'.
At C:\temp\lab-xml-validation\Test-Xml.ps1:8 char:42
+     [scriptblock] $ValidationEventHandler = { Write-Error $args[1].Exception }
+                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException