powershell - 根据错误结果循环遍历文件(使用 Powershell)并一次移动一个文件的问题
问题描述
我正在使用 Powershell 针对多个 XSD 验证多个 XML 文件;这部分代码按预期工作,但是我还需要将任何无法验证的 XML 移动到“无效”文件夹。我正在尝试使用 ForEach 遍历这些文件,然后 - 使用 If 语句 - 移动任何出错的文件。我的问题是所有文件都被移动,无论它们是否出错。
我已经用尽可能多的不同方式编写了这个循环,但我没有得到我期望的结果。(我也在网上搜索了几天以找到答案。)我需要 ForEach 将代码应用于每个文件,一次一个。这是我的语法问题吗?也许我错过了一些非常明显的东西,但我现在不知所措。
我正在使用这个函数(在 Stack Overflow 上找到,如图所示,稍作调整)来验证 XML。
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)]
[SupportsWildcards()]
$SchemaFile,
[Parameter(ValueFromPipeline=$true, Mandatory=$true)]
[SupportsWildcards()]
[alias('Fullname')]
$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()
}
}
以下是我选择 XML 以针对其给定模式进行验证的方式。
$allfiles = "..\Schema Validation\XMLs\*.xml"
$xml1 = Get-ChildItem $allfiles -Recurse | Select-String "<UniqueElement>" -List | Resolve-Path
$xml2 = Get-ChildItem $allfiles -Recurse | Select-String "<UniqueElement>" -List | Resolve-Path
$xsd1 = "..\Schema Validation\Schemas\Schema1.xsd"
$xsd2 = "..\Schema Validation\Schemas\Schema2.xsd"
这是对我不起作用的 ForEach 循环。(在其当前配置中,尽管我已经编写了十几种不同的方式。)
ForEach ($xml in $xml1) {
$xml | Test-XmlFile $xsd1
If ($Error) {
$Error[0].Exception, "`r" | Out-File "..\Schema Validation\Results\log.txt"
Move-Item $xml -Destination "..\Schema Validation\Invalid"
}}
上面的 ForEach 循环也对 $xml2 和 $xsd2 变量重复。(正如您从 Out-File 中看到的那样,我还在一个文本文件中捕获异常消息以用于各种日志。)
由于“If ($Error)”语句以及我试图一次遍历文件的事实,我只希望移动那些出错并遇到异常的 XML;但是,发生的情况是,任何包含将其标识为 $xml1 或 $xml2 组的一部分的唯一字符串的 XML 都将移动到 Invalid 文件夹,错误或无错误。那么我错过了什么令人痛苦的显而易见的事情?(顺便说一句,异常文本按预期填充错误日志,因此至少该部分按我希望的那样工作。)
编辑:再想一想,我不应该说异常文本“按预期”填充了日志。它确实填充了日志,但是对于变量中包含的每个文件(例如,$xml1 中的每个文件),它都会将消息写入日志文件一次,无论文件是否实际出错。因此,如果 $xml1 中有两个文件,但只有一个无效,则该无效文件的单个异常消息将被写入日志两次。所以它为每个循环的文件写一些东西,不管有效性或错误。希望这是有道理的。
解决方案
$Error
为您提供最后一个错误的列表,如果上一个操作成功,它不会被清除 - 它仍然包含最后遇到的错误。因此,在第一个错误之后,每个文件都将被复制到“无效”目录。
您已经在 cmdlet 中进行了错误处理,因此您可以修改该代码以同时处理将文件移动到其他目录的问题。
推荐阅读
- javascript - 在 netlify 上托管的 gatsby 网站中启用 301 重定向规则
- reactjs - 无法获取错误 400 错误请求的数据
- node.js - 如何在node.js中替换/更新特定mongodb集合的整个文档
- java - 创建弹出窗口
- python - 从 ipyparallel 进程中不断更新和清除标准输出
- java - Minecraft 1.16.5 织物改装 - 矿石
- model-view-controller - 在 3 层网络架构 MVC 应用程序中管理 web.config db 连接
- windows - 从批处理脚本中的外部文件中的标记读取值
- laravel - Nginx 配置在我的 docker 容器上不起作用
- python - 通配符 Snakemake 规则的预处理