Powershell 中的 XML 解析器并在验证后移动文件

问题描述 投票:0回答:0

以下脚本已经运行良好。我可以根据

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 在我尝试移动文件之前关闭。但是文件仍然是块,我不知道为什么。

powershell xml-parsing xsd-validation
© www.soinside.com 2019 - 2024. All rights reserved.