【问题标题】:Perform XML Validation using a Variable instead of File使用变量而不是文件执行 XML 验证
【发布时间】:2018-05-12 07:33:00
【问题描述】:

我正在使用找到的代码 here 来执行 XML 验证:

function Test-Xml {
[cmdletbinding()]
param(
    [parameter(mandatory=$true)]$InputFile,
    $Namespace = $null,
    [parameter(mandatory=$true)]$SchemaFile
)

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

PROCESS {
    if ($inputfile)
    {
        write-verbose "input file: $inputfile"
        write-verbose "schemafile: $SchemaFile"
        $fileName = (resolve-path $inputfile).path
        if (-not (test-path $SchemaFile)) {throw "schemafile not found $schemafile"}
        $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, $SchemaFile) | Out-Null
        $readerSettings.add_ValidationEventHandler(
        {
            try {
                $detail = $_.Message 
                $detail += "`n" + "On Line: $($_.exception.linenumber) Offset: $($_.exception.lineposition)"
            } catch {}
            $failureMessages += $detail
            $failCount = $failCount + 1
        });
        try {
            $reader = [System.Xml.XmlReader]::Create($fileName, $readerSettings)
            while ($reader.Read()) { }
        }
        #handler to ensure we always close the reader sicne it locks files
        finally {
            $reader.Close()
        }
    } else {
        throw 'no input file'
    }
}

它工作正常,当 XML 和 XSD 模式是“真实文件”时,我可以验证 XML 文件。 现在假设两者都存储在 Variables 中:我已经替换了

$reader = [System.Xml.XmlReader]::Create($fileName, $readerSettings)

$reader = [System.Xml.XmlReader]::Create((new-Object System.IO.StringReader($String)), $readerSettings)

which DO WORK,但 StringReader 将所有格式正确的 XML 文件“折叠”到一行,因此 任何验证错误总是在行 1

有没有办法让 [System.Xml.XmlReader] 处理变量而不是文件,同时保留存储在变量中的格式?

非常感谢

【问题讨论】:

  • 我仍在积极寻找答案...

标签: .net xml powershell validation xsd


【解决方案1】:

我不认为你可以保留格式,但你可以重新格式化:

$StringWriter  = New-Object System.IO.StringWriter
$XmlTextWriter = New-Object System.XMl.XmlTextWriter $StringWriter
$XmlTextWriter.Formatting = "Indented"      # Default: None
$XmlTextWriter.Indentation = 2              # Default: 2
$XmlTextWriter.IndentChar = " "             # Default: Space
$String.WriteContentTo($XmlTextWriter)
"$StringWriter"

【讨论】:

  • 抱歉,我不明白:我有一个 [XML]$Variable,它在转换 .ToString() 或 .Save 时包含正确的格式。 StringWriter 如何在这种情况下发挥作用? (我使用 StringReader 来“欺骗”XmlReader 接受变量而不是文件)
  • 您写道:“StringReader 将所有格式正确的 XML 文件‘折叠’到一行,因此任何验证错误总是在第 1 行。”,所以我为您提供了一种扩展和重新格式化它的方法。无论如何,我看不出XML formatting 会如何影响 XML 字符串的验证(您有错误示例吗?)。顺便提一句。您应该能够使用:$Reader = [xml]$String 验证 XML 字符串(包括正确的 XSD 字符串。我在 "shiporder.xsd" 文件/字符串 w3schools.com/xml/schema_example.asp 上确认了这一点)。 (或者我还想念什么?)
  • XML 格式影响验证。但是,如果经过验证的 XML 是从字符串读取器中获取的,那么它会被验证为单个非常长的行。因此,[第 40 行,第 30 行] 上的错误变为 [第 1 行,第 341 行](仅作为示例)。重新格式化 xml 是一种选择,但给定的 XML 可能与原始 XML 的行数(或字符位置)不同,从而误导了验证错误的位置。例如,使用上面的例子,[Row 40, position 30] 可能变成 [Row 39, position 28]
猜你喜欢
  • 2016-05-20
  • 1970-01-01
  • 1970-01-01
  • 2022-06-13
  • 1970-01-01
  • 1970-01-01
  • 2018-01-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多