Me doy cuenta de que esta es una vieja pregunta, sin embargo, probé las respuestas proporcionadas y no pude conseguir que funcionen correctamente en Powershell.
He creado la siguiente función que utiliza algunas de las técnicas que se describen aquí. Lo he encontrado muy confiable.
Tuve que validar documentos XML antes en varias ocasiones, sin embargo, siempre encontré que el número de línea era 0. Parece que XmlSchemaException.LineNumber
solo estará disponible durante la carga del documento.
Si lo hace después de validación usando el método Validate()
en una XmlDocument
continuación LineNumber/LinePosition siempre será 0.
lugar que debe hacer la validación durante la lectura utilizando un XmlReader
y la adición de un controlador de eventos de validación para un bloque de secuencia de comandos .
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
}
¿Por qué exactamente lo necesita ser PowerShell simplemente porque está leyendo una lista de archivos de stdin? –
Me gustaría poder integrarlo fácilmente en scripts de compilación automatizados. No quería tener que compilar una aplicación solo para hacer esto. Un script de PowerShell parecía una forma natural para este tipo de cosas. –