以下脚本已经运行良好。我可以根据
xml
文件验证我给定的 xsd
文件并记录所有验证错误。
我的问题是,如果没有发生验证错误,我想移动 xml
文件。但是我不知道在哪里放置move-item
声明。我总是得到错误file can not moved because it is still in use.
这是代码。希望有人能帮忙。
# Get all XML files in the folder that start with "products"
$xmlFiles = Get-ChildItem -Path $sourceDir -Filter products*.xml
foreach ($xmlFile in $xmlFiles) {
$path = ""
$path = $sourceDir + $xmlFile
# Checking if file exits
if (-not (Test-Path $path)) {
Write-Warning "The XML file $path does not exist."
logger -ErrMessage "File not exits." -log_file $logfile -xml_file $path
# Checking if file is readable
} elseif ((Get-Item $path).IsReadOnly) {
Write-Warning "XML file not readable: $path"
logger -ErrMessage "File not readable." -log_file $logfile -xml_file $path
} else {
# Set up validation settings
$valSettings = [System.Xml.XmlReaderSettings]::new();
$valSettings.ValidationType = [System.Xml.ValidationType]::Schema;
$valSettings.CheckCharacters = $true;
$valSettings.ValidationFlags = ([System.Xml.Schema.XmlSchemaValidationFlags]::ProcessIdentityConstraints -bor [System.Xml.Schema.XmlSchemaValidationFlags]::ReportValidationWarnings)
$valSettings.Schemas.Add($URL, $xsdFilename);
# Store validation errors in an array
$errors = New-Object System.Collections.Generic.List[System.Xml.Schema.ValidationEventArgs]
# Create a validation event handler
$validationHandler = {
param ([object] $sender, [System.Xml.Schema.ValidationEventArgs] $e)
$lineNumber = ""
$linePosition = ""
# Get the line number and position of the error
# if ($e.Exception) {
$lineNumber = $e.Exception.LineNumber
$linePosition = $e.Exception.LinePosition
# }
if ($e.Severity -eq [System.Xml.Schema.XmlSeverityType]::Warning) {
Write-Host("WARNING___: ")
Write-Warning($e.Message, $lineNumber)
Write-Host("--Line: $lineNumber, Position: $linePosition")
logger -ErrMessage $e.Message -line $lineNumber -log_file $logfile -xml_file $path
}
elseif ($e.Severity -eq [System.Xml.Schema.XmlSeverityType]::Error) {
if ($e.Exception -and $e.Exception.Message.StartsWith("The 'text' element is not declared.")) {
$e.Severity = [System.Xml.Schema.XmlSeverityType]::Warning
Write-Host("WARNING___: ")
Write-Warning($e.Exception.Message)
Write-Host("--Line: $lineNumber, Position: $linePosition")
logger -ErrMessage $e.Message -line $lineNumber -log_file $logfile -xml_file $path
}
else {
$errors.Add($e)
Write-Warning $e.Message;
Write-Host("--Line: $lineNumber, Position: $linePosition");
if (![string]::IsNullOrEmpty($logfile)) {
#write-host $e.Exception.GetType().FullName
logger -ErrMessage $e.Message -line $lineNumber -log_file $logfile -xml_file $path
}
}
}
}
# Set up validation event handler to capture errors
#$valSettings.ValidationEventHandler += {$errors.Add($_)}#/ turn it on, if 'Add_ValidationEventHandler' runs into error
$valSettings.Add_ValidationEventHandler($validationHandler)
$xmlReader = [System.Xml.XmlReader]::Create([System.IO.File]::OpenRead($path), $valSettings);
try {
# Read each xml node, validate it and close the xml file
while ($xmlReader.Read()) { }
$xmlReader.close()
#logger -ErrMessage "The file is in use by another process." -log_file $logfile -xml_file $path
} catch{
$lineNumber = ""
$linePosition = ""
# if ($_.Exception) {
$lineNumber = [regex]::Match($_.Exception.Message, "Zeile (\d+)").Groups[1].Value
$linePosition = [regex]::Match($_.Exception.Message, "Position (\d+)").Groups[1].Value
# }
$errorDesc = $_.Exception.Message
write-warning $_.Exception.Message
Write-Host("--Line: $lineNumber, Position: $linePosition")
logger -ErrMessage $errorDesc -line $lineNumber -log_file $logfile -xml_file $path
}
finally {
# make sure the xml reader is closed even if an exception occurs
if ($xmlReader -ne $null) {
$xmlReader.Dispose()
$xmlReader.close()
Move-Item $xmlFile.FullName $destination -Force
}
}
} #End If-else
} #End ForEach Loop
创建的 xmlReader 在我尝试移动文件之前关闭。但是文件仍然是块,我不知道为什么。