假设我想在我的自定义工具箱模块中创建一个函数,该函数使用一些自定义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文件中的模式地址?
答案 0 :(得分: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-File有什么问题。
答案 1 :(得分: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.
注意:
XmlReaderSettings
的文档和ValidationEventArgs
(一开始)将是有益的。schemaLocation
属性(来自http://www.w3.org/2001/XMLSchema-instance
命名空间),其中包含{namespace,XSD-schmea}对的列表。但是,XmlReaderSettings.Schemas
也可用于指定文档外的模式。答案 2 :(得分:1)
指定XSD文件的文件路径,最好通过相对路径,除非XSD存储在您计划运行脚本的每台PC上的一个众所周知的路径中。对于相对路径,是的,使用$ PSScriptRoot,例如
$xsd = $PSScriptRoot\schema.xsd
Test-Xml -XmlPath $xmlPath -SchemaPath $xsd
答案 3 :(得分:0)
我不太确定您是否要将XML有效性作为程序或服务的函数来检查。
首先,在XML中有很多东西需要学习,我找到了一个我正在研究的资源:learn XML in a weekend。您可能会觉得这很有帮助。你不必一次就知道其中的所有内容。
这是一个online service,它将检查XML文档的有效性。
如果你想让一个程序能够做到这一点,我认为你需要某种xml lint,可能是这样的:xmlint。
最后,如果你想编写一个使用像API这样的xml lint的程序,那么你应该指定你正在使用的编程语言。希望这会有帮助。干杯!