我想將XML驗證添加到現有的Powershell腳本。我用C#編寫代碼作爲概念證明,但是當我移植到Powershell並使用相同的輸入文件時,我得到了不同的結果。我使用Powershell 3.0。Powershell XML驗證
我已經工作的C#代碼是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Schema;
namespace SchemaTest
{
class Program
{
const string SCHEMA_PATH = @"C:\Test\test_schema.xsd";
const string XML_PATH = @"C:\Test\test.xml";
static void Main(string[] args)
{
XmlReader schemaReader = XmlReader.Create(SCHEMA_PATH);
XmlSchema schema = XmlSchema.Read(
schemaReader,
(Object sender, ValidationEventArgs e) =>
{
Console.Out.WriteLine("Error reading schema file");
}
);
schemaReader.Close();
XmlReaderSettings rSettings = new XmlReaderSettings();
rSettings.ValidationType = ValidationType.Schema;
rSettings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
rSettings.Schemas.Add(schema);
rSettings.ValidationEventHandler += (Object sender, ValidationEventArgs e) =>
{
Console.Out.WriteLine("Error validating XML file");
};
XmlReader configReader = XmlReader.Create(XML_PATH, rSettings);
XmlDocument doc = new XmlDocument();
doc.Load(configReader);
configReader.Close();
Console.ReadKey(true);
}
}
}
我有一個簡單的XSD架構和相應的(無效的)XML文件,其產生預期的「錯誤驗證XML文件」,從rSettings.ValidationEventHandler
消息時與運行這段代碼。
我已經寫了相應的PowerShell代碼如下:
$schemaReader = [System.Xml.XmlReader]::Create('C:\Test\test_schema.xsd')
[System.Xml.Schema.ValidationEventHandler]$schemaValidationHandler = { Write-Output "Error reading schema file" }
$schema = [System.Xml.Schema.XmlSchema]::Read($schemaReader, $schemaValidationHandler)
$schemaReader.Close()
$rSettings = New-Object -Type System.Xml.XmlReaderSettings
$rSettings.ValidationType = [System.Xml.ValidationType]::Schema
$rSettings.ValidationFlags = $rSettings.ValidationFlags -bor [System.Xml.Schema.XmlSchemaValidationFlags]::ReportValidationWarnings
$rSettings.Schemas.Add($schema)
Register-ObjectEvent -InputObject $rSettings -EventName ValidationEventHandler -Action { Write-Output 'Error validating XML file' }
$configReader = [System.Xml.XmlReader]::Create('C:\Test\test.xml', $rSettings)
$doc = New-Object -TypeName System.Xml.XmlDocument
$doc.Load($configReader)
$configReader.Close()
當我運行鍼對相同的XSD和XML文件的代碼,我沒有得到「錯誤驗證XML文件」輸出我預計。
爲了排除故障,我將Register-ObjectEvent
調用註釋掉了,並且驗證我在調用$doc.Load($configReader)
行時遇到了異常。這導致我認爲註冊事件處理程序存在問題,但我似乎無法找到替代方案。
爲了完整起見,這裏是我使用來測試這個XSD和XML文件:
test_schema.xsd:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.test.com"
xmlns="http://www.test.com"
elementFormDefault="qualified"
version="1.0.0">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="age" type="xs:int" />
<xs:element name="city" type="xs:string" />
</xs:sequence>
<xs:attribute name="id" type="xs:int" />
</xs:complexType>
</xs:element>
</xs:schema>
的test.xml:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<root
xmlns="http://www.test.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
id="1">
<name>Joe</name>
<!-- Comment out <age> tags for testing
<age>20</age>
-->
<city>New York City</city>
</root>
我認爲問題在於您在事件處理程序中使用了寫入輸出。如果您嘗試將其更改爲Write-Host(僅用於測試,而不是用於保存),則會看到它按預期寫入。 –
@ robert.westerlund這工作 - 我添加了'寫輸出',因爲只是引用字符串不工作......我沒有嘗試第三個('寫主機')選項。爲什麼在這種情況下'Write-Output'沒有工作?由於管道中沒有別的東西,爲什麼當它在腳本塊中時,它會寫入Out-Default,正如[本文]中所述(http://stackoverflow.com/questions/8755497/which-shaould -i-use-write-host-write-output-or-consolewriteline) – TWReever
寫輸出通常是您應該用來從某個方法獲取輸出的一個輸出(除非您的方法是用動詞Show命名的,根據我們正在討論的輸出類型,可以使用Write-Host cmdlet)或Write-Verbose,Write-Debug,Write-Warning或Write-Error。我不確定Write-Output如何處理事件(雖然還沒有閱讀或嘗試過),但是我可以想象它們是在不同的範圍內運行的(特別是因爲你真的不知道當一個事件處理程序將被調用)。 –