如何使用PowerShell针对XSD验证XML文件?

Fla*_*DOA 25 xml powershell xsd

作为我开发的一部分,我希望能够针对单个XSD文件验证整个文件夹的XML文件.PowerShell函数似乎是一个很好的候选者,因为我可以像这样管道一个文件列表:dir*.xml | Validate-Xml -Schema.\ MySchema.xsd

我已经考虑过在C#问题中从参考XSD验证一个Xml中移植C#代码,但我不知道如何在PowerShell中添加处理程序.

edd*_*ves 15

PowerShell的社区扩展有一个测试的XML cmdlet的.唯一的缺点是扩展还没有更新一段时间,但大多数都在最新版本的PowerShell(包括Test-Xml)上工作.只需做一个Get-Childitem并将列表传递给foreach,在每个上面调用Test-Xml.


Fla*_*DOA 12

我写了一个PowerShell函数来做到这一点:

用法:

dir*.xml | Test-Xml -Schema".\ MySchemaFile.xsd"-Namespace" http://tempuri.org "

码:

function Test-Xml {
param(
    $InputObject = $null,
    $Namespace = $null,
    $SchemaFile = $null
)

BEGIN {
    $failCount = 0
    $failureMessages = ""
    $fileName = ""
}

PROCESS {
    if ($InputObject -and $_) {
        throw 'ParameterBinderStrings\AmbiguousParameterSet'
        break
    } elseif ($InputObject) {
        $InputObject
    } elseif ($_) {
        $fileName = $_.FullName
        $readerSettings = New-Object -TypeName System.Xml.XmlReaderSettings
        $readerSettings.ValidationType = [System.Xml.ValidationType]::Schema
        $readerSettings.ValidationFlags = [System.Xml.Schema.XmlSchemaValidationFlags]::ProcessInlineSchema -bor
            [System.Xml.Schema.XmlSchemaValidationFlags]::ProcessSchemaLocation -bor 
            [System.Xml.Schema.XmlSchemaValidationFlags]::ReportValidationWarnings
        $readerSettings.Schemas.Add($Namespace, $SchemaFile) | Out-Null
        $readerSettings.add_ValidationEventHandler(
        {
            $failureMessages = $failureMessages + [System.Environment]::NewLine + $fileName + " - " + $_.Message
            $failCount = $failCount + 1
        });
        $reader = [System.Xml.XmlReader]::Create($_, $readerSettings)
        while ($reader.Read()) { }
        $reader.Close()
    } else {
        throw 'ParameterBinderStrings\InputObjectNotBound'
    }
}

END {
    $failureMessages
    "$failCount validation errors were found"
}
}
Run Code Online (Sandbox Code Playgroud)


wan*_*gzq 10

我想评论当前接受的答案中的脚本不验证有关元素的错误顺序的错误xs:sequence.例如:test.xml

<addresses xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation='test.xsd'>
  <address>
    <street>Baker street 5</street>
    <name>Joe Tester</name>
  </address>
</addresses>
Run Code Online (Sandbox Code Playgroud)

test.xsd

<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>    
<xs:element name="addresses">
      <xs:complexType>
       <xs:sequence>
         <xs:element ref="address" minOccurs='1' maxOccurs='unbounded'/>
       </xs:sequence>
     </xs:complexType>
    </xs:element>

     <xs:element name="address">
      <xs:complexType>
       <xs:sequence>
         <xs:element ref="name" minOccurs='0' maxOccurs='1'/>
         <xs:element ref="street" minOccurs='0' maxOccurs='1'/>
       </xs:sequence>
      </xs:complexType>
     </xs:element>

     <xs:element name="name" type='xs:string'/>
     <xs:element name="street" type='xs:string'/>
    </xs:schema>
Run Code Online (Sandbox Code Playgroud)

我写了另一个可以报告此错误的版本:

function Test-XmlFile
{
    <#
    .Synopsis
        Validates an xml file against an xml schema file.
    .Example
        PS> dir *.xml | Test-XmlFile schema.xsd
    #>
    [CmdletBinding()]
    param (     
        [Parameter(Mandatory=$true)]
        [string] $SchemaFile,

        [Parameter(ValueFromPipeline=$true, Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
        [alias('Fullname')]
        [string] $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()
    }
}
Run Code Online (Sandbox Code Playgroud)

PS C:\ temp\lab-xml-validation> dir test.xml | Test-XmlFile test.xsd

System.Xml.Schema.XmlSchemaValidationException: The element 'address' has invalid child element 'name'.
...
Run Code Online (Sandbox Code Playgroud)

  • 你的答案很好,简短而有效:)你只是错过了`$schemaReader.Dispose()`,这会导致模式文件锁定 (2认同)