.net C++\CLI-如何将成员函数设置为xmlDocument::Schemas::ValidationEventHandler的处理程序
我试图在Visual Studio 2012中,在C++/CLI中将成员函数设置为XmlDocument数据成员的处理程序。处理程序函数如下所示.net C++\CLI-如何将成员函数设置为xmlDocument::Schemas::ValidationEventHandler的处理程序,.net,xml,visual-c++,c++-cli,.net,Xml,Visual C++,C++ Cli,我试图在Visual Studio 2012中,在C++/CLI中将成员函数设置为XmlDocument数据成员的处理程序。处理程序函数如下所示 void Validate ( System :: Object ^ sender, System :: Xml :: Schema :: ValidationEventArgs ^ xmlException ) { switch ( xmlException->Severity ) {
void Validate ( System :: Object ^ sender, System :: Xml :: Schema :: ValidationEventArgs ^ xmlException ) {
switch ( xmlException->Severity ) {
case System :: Xml :: Schema :: XmlSeverityType :: Error : {
System :: Console :: WriteLine ( "Object: {0}", sender->ToString () );
System :: Console :: WriteLine ( " Error: {0}", xmlException->Message );
} break;
case System :: Xml :: Schema :: XmlSeverityType :: Warning : {
System :: Console :: WriteLine ( " Object: {0}", sender->ToString () );
System :: Console :: WriteLine ( "Warning: {0}", xmlException->Message );
} break;
default : {
System :: Console :: WriteLine ( "An unknown XML Exception has occured:\n\n Object: {0}", sender->ToString () );
System :: Console :: WriteLine ( "Exception: {0}", xmlException->Message );
} break;
}
};
…这没什么特别的
这就是我的数据成员的外观
System :: Xml :: XmlDocument ^ xmlDocument;
…这就是我试图在类构造函数中设置它的方式:
xmlDocument->Schemas->ValidationEventHandler += gcnew System :: Xml :: Schema :: ValidationEventArgs ( this, & MyClass :: Validate );
我的问题是我收到错误C3767:候选函数不可访问,即使我的“验证”成员函数及其定义的类被指定为public
我尝试了很多方法,最近使用了EventArgs或使用“#pragma make_public(System::Xml::Schema::ValidationEventArgs)”,但都没有效果
我的头发快用完了,想把头发拔出来,所以任何帮助都将不胜感激。谢谢大家。首先,出现编译器错误C3767的原因是您需要执行以下操作:
schemas->ValidationEventHandler += gcnew System::Xml::Schema::ValidationEventHandler(this, &MyClass::Validate);
而不是gcnew ValidationEventArgs
其次,请注意,XmlSchemaSet.ValidationEventHandler
可能不会按您的想法执行。从:
设置事件处理程序,用于在调用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
时,会从读取器的schemaset
属性(重新)加载对象
然后,原型实现将如下所示:
#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;
}
};
#包括“stdafx.h”
#使用
#使用
#使用
使用名称空间系统;
使用名称空间系统::Xml;
使用名称空间System::Xml::Schema;
void MyClass::AddSchema(系统::字符串^targetNamespace,系统::字符串^schemaUri)
{
尝试
{
模式->添加(targetNamespace,schemaUri);
xmlDocument->Schemas=Schemas;
}
捕获(异常^ex)
{
控制台::WriteLine(ex->ToString());
//可能是重新命名。
}
}
void MyClass::LoadDocument(系统::字符串^inputUri)
{
XmlReader^reader=nullptr;
尝试
{
ValidationEventHandler^eventHandler=gcnew System::Xml::Schema::ValidationEventHandler(this,&MyClass::ValidateXml);
XmlReaderSettings^settings=gcnew XmlReaderSettings();
设置->模式=模式;
设置->验证类型=验证类型::模式;
设置->验证eventHandler+=eventHandler;
reader=XmlReader::Create(输入URI,设置);
xmlDocument->Load(读卡器);
读卡器->关闭();
}
捕获(异常^ex)
{
控制台::写线(ex->Message);
//可能是重新命名。
}
最后
{
//确保在发生异常时关闭读卡器。
删除阅读器;
}
}
void MyClass::validatedDocument()
{
ValidationEventHandler^eventHandler=gcnew System::Xml::Schema::ValidationEventHandler(this,&MyClass::ValidateXml);
xmlDocument->Validate(eventHandler);
}
void MyClass::ValidateSchema(系统::对象^sender,系统::Xml::架构::ValidationEventArgs ^xmlException)
{
验证(发送方、xmlException、gcnew System::字符串(“模式:”);
}
void MyClass::ValidateXml(系统::对象^sender,系统::Xml::架构::ValidationEventArgs^xmlException)
{
验证(发送方、xmlException、系统::字符串::空);
}
void MyClass::Validate(系统::对象^sender,系统::Xml::架构::ValidationEventArgs ^xmlException,系统::字符串^prefix)
{
开关(xmlException->严重性)
{
案例系统::Xml::架构::XmlSeverityType::错误:
{
System::Console::WriteLine(前缀+“对象:{0}”,发送方->ToString());
System::Console::WriteLine(前缀+“Error:{0}”,xmlException->Message);
}中断;
案例系统::Xml::架构::XmlSeverityType::警告:
{
System::Console::WriteLine(前缀+“对象:{0}”,发送方->ToString());
System::Console::WriteLine(前缀+“警告:{0}”,xmlException->Message);
}中断;
违约:
{
System::Console::WriteLine(前缀+“发生未知XML异常:\n\n对象:{0}”,发件人->ToString());
System::Console::WriteLine(前缀+“异常:{0}”,xmlException->Message);
}中断;
}
};
首先,出现编译器错误C3767的原因是您需要执行以下操作:
schemas->ValidationEventHandler += gcnew System::Xml::Schema::ValidationEventHandler(this, &MyClass::Validate);
而不是gcnew ValidationEventArgs
其次,请注意,XmlSchemaSet.ValidationEventHandler
可能不会按您的想法执行。从:
设置事件处理程序,用于在调用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
时,会从读取器的schemaset
属性(重新)加载对象
然后,原型实现将如下所示:
#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;
}
};
#包括“stdafx.h”
#使用
#使用
#使用
使用名称空间系统;
乌辛