I'm trying to add XML validation to an existing Powershell script. I've written code in C# as a proof of concept, but when I port to Powershell and use the same input files, I'm getting different results. I'm using Powershell 3.0.
The C# code I have working is:
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);
}
}
}
I have a simple XSD schema and corresponding (invalid) XML file, which produces the expected "Error validating XML file" message from the rSettings.ValidationEventHandler
when run with this code.
The corresponding Powershell code I've written is as follows:
$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()
When I run this code against the same XSD and XML file, I don't get the "Error validating XML file" output as I expect.
To troubleshoot, I commented out the Register-ObjectEvent
call, and verified that I am getting an exception when the $doc.Load($configReader)
line is called. This leads me to think there is an issue with registering the event handler, but I can't seem to find an alternative.
For completeness, here are the XSD and XML files I'm using to test this:
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>