首先,您收到编译器错误 C3767 的原因是您需要这样做:
schemas->ValidationEventHandler += gcnew System::Xml::Schema::ValidationEventHandler(this, &MyClass::Validate);
而不是gcnew ValidationEventArgs。
其次,请注意XmlSchemaSet.ValidationEventHandler 可能不会按照您的想法行事。来自documentation:
设置一个事件处理程序,用于在调用 XmlSchemaSet 的 Add 或 Compile 方法时接收有关架构验证错误的信息。
因此,如果您要为无效的 XML 文档添加事件处理程序,那就不是这样了。这是针对架构本身的错误。
如果您希望创建一个包含 XmlDocument 的类,但还允许调用者加载架构并针对它验证 XmlDocument,您可以执行以下操作:
public ref class MyClass
{
public:
MyClass()
{
xmlDocument = gcnew System::Xml::XmlDocument();
schemas = gcnew System::Xml::Schema::XmlSchemaSet();
// Set the callback for errors in the schema itself.
schemas->ValidationEventHandler += gcnew System::Xml::Schema::ValidationEventHandler(this, &MyClass::ValidateSchema);
xmlDocument->Schemas = schemas;
}
// Adds a schema to the current schema set.
void AddSchema(System::String ^targetNamespace, System::String ^schemaUri);
// Loads the specified document, validating it against the current schema set.
void LoadDocument(System::String ^inputUri);
// Validates the current document against the current schema set.
void ValidateDocument();
System::Xml::XmlDocument ^ GetDocument() { return xmlDocument; }
private:
// Validation callback for errors in the schema itself.
void ValidateSchema ( System :: Object ^ sender, System :: Xml :: Schema :: ValidationEventArgs ^ xmlException );
// Validation callback for errors in the XML document.
void ValidateXml ( System :: Object ^ sender, System :: Xml :: Schema :: ValidationEventArgs ^ xmlException );
// Lower level callback for both schema and XML errors.
void Validate ( System :: Object ^ sender, System :: Xml :: Schema :: ValidationEventArgs ^ xmlException, System::String ^ prefix );
System::Xml::XmlDocument ^ xmlDocument;
System::Xml::Schema::XmlSchemaSet ^schemas;
};
单独缓存XmlSchemaSet 很方便,因为当使用来自XmlReader 的XML 数据初始化XmlDocument 时,XmlDocument.Schemas 对象将从阅读器的Schemas 属性(重新)加载.
那么原型实现将如下所示:
#include "stdafx.h"
#using <mscorlib.dll>
#using <System.dll>
#using <System.Xml.dll>
using namespace System;
using namespace System::Xml;
using namespace System::Xml::Schema;
void MyClass::AddSchema(System::String ^targetNamespace, System::String ^schemaUri)
{
try
{
schemas->Add(targetNamespace, schemaUri);
xmlDocument->Schemas = schemas;
}
catch (Exception ^ex)
{
Console::WriteLine(ex->ToString());
// Possibly rethrow.
}
}
void MyClass::LoadDocument (System::String ^inputUri)
{
XmlReader^ reader = nullptr;
try
{
ValidationEventHandler^ eventHandler = gcnew System::Xml::Schema::ValidationEventHandler(this, &MyClass::ValidateXml);
XmlReaderSettings^ settings = gcnew XmlReaderSettings();
settings->Schemas = schemas;
settings->ValidationType = ValidationType::Schema;
settings->ValidationEventHandler += eventHandler;
reader = XmlReader::Create(inputUri, settings);
xmlDocument->Load(reader);
reader->Close();
}
catch (Exception ^ex)
{
Console::WriteLine(ex->Message);
// Possibly rethrow.
}
finally
{
// Make sure the reader is closed in the event of an exception.
delete reader;
}
}
void MyClass::ValidateDocument()
{
ValidationEventHandler^ eventHandler = gcnew System::Xml::Schema::ValidationEventHandler(this, &MyClass::ValidateXml);
xmlDocument->Validate(eventHandler);
}
void MyClass::ValidateSchema ( System :: Object ^ sender, System :: Xml :: Schema :: ValidationEventArgs ^ xmlException)
{
Validate(sender, xmlException, gcnew System::String("Schema: "));
}
void MyClass::ValidateXml ( System :: Object ^ sender, System :: Xml :: Schema :: ValidationEventArgs ^ xmlException )
{
Validate(sender, xmlException, System::String::Empty);
}
void MyClass::Validate ( System :: Object ^ sender, System :: Xml :: Schema :: ValidationEventArgs ^ xmlException, System::String ^ prefix )
{
switch ( xmlException->Severity )
{
case System :: Xml :: Schema :: XmlSeverityType :: Error :
{
System :: Console :: WriteLine ( prefix + "Object: {0}", sender->ToString () );
System :: Console :: WriteLine ( prefix + " Error: {0}", xmlException->Message );
} break;
case System :: Xml :: Schema :: XmlSeverityType :: Warning :
{
System :: Console :: WriteLine ( prefix + " Object: {0}", sender->ToString () );
System :: Console :: WriteLine ( prefix + "Warning: {0}", xmlException->Message );
} break;
default :
{
System :: Console :: WriteLine ( prefix + "An unknown XML Exception has occured:\n\n Object: {0}", sender->ToString () );
System :: Console :: WriteLine ( prefix + "Exception: {0}", xmlException->Message );
} break;
}
};