2

假设我想在我的自定义工具箱模块中创建一个函数,该函数使用一些自定义 xml 文件来提供指令(使用$xmlpath参数传递)。如何确保输入使用正确的 xml 类型/语法/格式(正确的元素、根节点等)?我读过关于模式(xsd)和命名空间(不明白这一点)。

如果我使用模式文件:如何使用 ex.xml 验证 xml。测试 XML(PSCX cmdlet)?我是否在线存储 xsd 文件并在 xml 文档中指定它的路径?我是否将其存储在我的模块文件夹中并将其硬编码到脚本中?如果是这样,我如何指定模式路径?代码示例:

#Stored in ..\Modules\MyModule\Process-Config.psm1)
function Process-Config
{
    param($xmlpath)
    #Test that file is xml
    try{ $xml = [xml](Get-Content $xmlpath) } catch {}

    #Test that xml-file is valid against schema in Module-folder (Modules\MyModule\xmlschema.xsd)
    #Using Test-XML PSCX cmdlet
    Test-XML -Path $xmlpath -SchemaPath #Schemapath#

}

编辑:我发现 $PSScriptRoot 提供了模块位置,所以我可以使用 $PSScriptRoot\Schemas\MySchema.xsd 作为路径。我认为它只适用于脚本,但似乎功能也适用。:-) 不过,我是否在 xml 中为这样的本地文件指定架构?如果是这样,我该如何指定这个本地路径,或者我应该也在线发布 xsd,以将其作为 xml 文件中的模式地址?

4

4 回答 4

7

如果您想要对 XML 文件进行基本测试(不验证 XML Schemata 或对外部模块的依赖),您可以使用来自 Jonathan Medd 的函数 Test-XMLFile

function Test-XMLFile {
    <#
        .SYNOPSIS
        Test the validity of an XML file
    #>
    [CmdletBinding()]
    param (
        [parameter(mandatory=$true)][ValidateNotNullorEmpty()][string]$xmlFilePath
    )

    # Check the file exists
    if (!(Test-Path -Path $xmlFilePath)){
        throw "$xmlFilePath is not valid. Please provide a valid path to the .xml fileh"
    }
    # Check for Load or Parse errors when loading the XML file
    $xml = New-Object System.Xml.XmlDocument
    try {
        $xml.Load((Get-ChildItem -Path $xmlFilePath).FullName)
        return $true
    }
    catch [System.Xml.XmlException] {
        Write-Verbose "$xmlFilePath : $($_.toString())"
        return $false
    }
}

如果你想检查很多 XML 文件,你可以使用类似的东西

gci -recurse *.xml |% {
 $outcome = Test-XMLFile $_.FullName -Verbose
}

它会告诉你哪个 XML 文件有什么问题。

于 2014-04-07T13:51:53.393 回答
2

这未经测试,但基于我编写的一个实用程序,用于检查 XML 与它声明使用的模式。它的核心是创建一个XmlReader配置为执行基于 XSD 的验证并允许加载引用的模式。

$readerSettings = New-Object 'System.Xml.XmlReaderSettings';
$readerSettings.ValidationFlags = [System.Xml.Schema.XmlSchemaValidationFlags]::ProcessInlineSchema -bor
                                  [System.Xml.Schema.XmlSchemaValidationFlags]::ProcessSchemaLocation -bor
                                  [System.Xml.Schema.XmlSchemaValidationFlags]::ReportValidationWarnings -bor
                                  [System.Xml.Schema.XmlSchemaValidationFlags]::ProcessIdentityConstraints;
$readerSettings.ValidationType = [System.Xml.ValidationType]::Schema;

$results = @()

$valHandler = [System.Xml.Schema.ValidationEventHandler]{
  # $_ is the second argument of type System.Xml.ValidationEventArgs
  $script:results += "{0}: {1}" -f $_.Severity, $_.Message;
}

$readerSettings.add_ValidationEventHandler($valHandler)

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

while ($reader.Read()) {
  # Do nothing...
}

$results;  # Return the array of validation errors and warnings.

笔记:

  • 在创建阅读器和处理 XML 时都会引发许多异常(例如,无效的 XML、找不到引用的模式)。
  • 可用的控件比此处显示的要多得多,通过文档XmlReaderSettingsValidationEventArgs(开始)将是有益的。
  • 为文件指定架构 (XSD) 的常用方法是使用包含 {namespace, XSD-schmea} 对列表的schemaLocation属性(来自命名空间)。http://www.w3.org/2001/XMLSchema-instance但是XmlReaderSettings.Schemas也可以用于指定文档之外的模式。
于 2013-01-20T22:49:21.177 回答
1

指定 XSD 文件的文件路径,最好通过相对路径指定,除非 XSD 存储在您计划运行脚本的每台 PC 上的众所周知的路径中。对于相对路径,是的,使用 $PSScriptRoot 例如

$xsd = $PSScriptRoot\schema.xsd
Test-Xml -XmlPath $xmlPath -SchemaPath $xsd
于 2013-01-21T03:01:53.657 回答
0

我不太确定您是要检查 XML 有效性作为程序的功能还是服务。

首先,在 XML 中有很多东西要学,我找到了一个我正在研究的资源:周末学习 XML。您可能会发现这很有帮助。您不必一口气了解其中的所有内容。

这是一个在线服务,它将检查 XML 文档的有效性。

如果您希望程序能够做到这一点,我认为您需要某种 xml lint,可能类似于:xmlint

最后,如果您想编写一个使用类似于 API 的 xml lint 的程序,那么您应该指定您使用的编程语言。希望这会有帮助。干杯!

于 2013-01-20T13:03:03.567 回答