如何验证xml的语法/格式是否正确(?)

问题描述 投票:2回答:4

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

如果我使用模式文件:如何使用ex验证xml。 Test-XML(PSCX cmdlet)?我是否在线存储xsd文件并在xml文档中指定它的路径?我将它存储在我的modules-folder中并将其硬编码到脚本中吗?如果是这样,我如何指定架构路径? Codesample:

#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文件中的模式地址?

xml powershell powershell-v3.0
4个回答
1
投票

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

$xsd = $PSScriptRoot\schema.xsd
Test-Xml -XmlPath $xmlPath -SchemaPath $xsd

7
投票

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

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文件有什么问题。


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,无法找到引用的模式),可以抛出许多异常。
  • 可用的控制比这里显示的要多得多,通过XmlReaderSettings的文档和ValidationEventArgs(一开始)将是有益的。
  • 为文件指定模式(XSD)的常用方法是使用schemaLocation属性(来自http://www.w3.org/2001/XMLSchema-instance名称空间),该属性包含{namespace,XSD-schmea}对的列表。但是,XmlReaderSettings.Schemas也可用于指定文档外的模式。

0
投票

我不太确定你是否要将XML有效性作为程序或服务的函数来检查。

首先,在XML中有很多东西需要学习,我找到了一个我正在研究的资源:learn XML in a weekend。您可能会觉得这很有帮助。你不必一次就知道其中的一切。

这是一个online service,它将检查XML文档的有效性。

如果你想要一个程序能够做到这一点,我认为你需要某种xml lint,可能是这样的:xmlint

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

© www.soinside.com 2019 - 2024. All rights reserved.