I came across a problem the other day where a process that relied on several external XML documents was failing due to a combination of factors:
- The document had been hand-edited
- The document contained UTF-8 characters
- The document had no encoding directive or BOM to identify it as containing UTF-8 characters
So, I knocked together the following PowerShell module to validate XML documents from the command line:
function Test-Xml {
param([string[]]$Path)
begin {
$xml = new-object System.Xml.XmlDocument
function TestXmlDocument([string]$path) {
$relativePath = Resolve-Path $path -Relative
Write-Host -NoNewLine "$relativePath : "
trap [System.Xml.XmlException] {
$script:valid = $false
$script:message = $_.Exception.Message
continue;
}
$script:valid = $true
$resolvedPath = Resolve-Path $path
$xml.Load($resolvedPath)
if ($script:valid) {
Write-Host -ForegroundColor Green "OK"
} else {
Write-Host -ForegroundColor Red "Failed - $script:message"
}
}
}
process {
if ($_ -is [IO.FileInfo]) {
TestXmlDocument $_.FullName
} elseif ($_ -is [string]) {
if (test-path -type Leaf $_) {
TestXmlDocument $_
}
}
}
end {
if ($Path) {
foreach ($aPath in $Path) {
TestXmlDocument $aPath
}
}
}
}
Export-ModuleMember Test-Xml
The function is implemented so that it can be invoked directly or as a filter. It can therefore be used to check a single file:
Test-Xml fileToCheck.xml
a list of files:
Test-Xml file1.xml, file2.xml, file3.xml
or against a set of files as part of a process:
Get-ChildItems -Recurse -Include *.xml,*.config | Test-Xml
The code is probably not as clean as it could be, but it gets the job done.