Add an XSD validation scheme and implement ParameterManager::CheckDocument(), function is used in the parameter editor

This commit is contained in:
wmayer
2019-10-14 22:56:03 +02:00
parent eff400620c
commit bd76bbd625
5 changed files with 136 additions and 2 deletions

View File

@@ -39,6 +39,8 @@
# include <xercesc/framework/StdOutFormatTarget.hpp>
# include <xercesc/framework/LocalFileFormatTarget.hpp>
# include <xercesc/framework/LocalFileInputSource.hpp>
# include <xercesc/framework/MemBufFormatTarget.hpp>
# include <xercesc/framework/MemBufInputSource.hpp>
# include <xercesc/parsers/XercesDOMParser.hpp>
# include <xercesc/util/XMLUni.hpp>
# include <xercesc/util/XMLUniDefs.hpp>
@@ -62,6 +64,7 @@
#endif
#include "Parameter.h"
#include "Parameter.inl"
#include "Exception.h"
#include "Console.h"
@@ -1369,6 +1372,7 @@ void ParameterManager::SaveDocument(XMLFormatTarget* pFormatTarget) const
#else
try {
std::unique_ptr<DOMPrintFilter> myFilter;
std::unique_ptr<DOMErrorHandler> myErrorHandler;
// get a serializer, an instance of DOMWriter
XMLCh tempStr[100];
@@ -1378,8 +1382,7 @@ void ParameterManager::SaveDocument(XMLFormatTarget* pFormatTarget) const
// set user specified end of line sequence and output encoding
theSerializer->setNewLine(gMyEOLSequence);
DOMConfiguration* config = theSerializer->getDomConfig();
config->setParameter(XStr("format-pretty-print").unicodeForm(),true);
//
// do the serialization through DOMWriter::writeNode();
@@ -1396,8 +1399,25 @@ void ParameterManager::SaveDocument(XMLFormatTarget* pFormatTarget) const
theSerializer->setFilter(myFilter.get());
}
// plug in user's own error handler
myErrorHandler.reset(new DOMPrintErrorHandler());
DOMConfiguration* config = theSerializer->getDomConfig();
config->setParameter(XMLUni::fgDOMErrorHandler, myErrorHandler.get());
// set feature if the serializer supports the feature/mode
if (config->canSetParameter(XMLUni::fgDOMWRTSplitCdataSections, gSplitCdataSections))
config->setParameter(XMLUni::fgDOMWRTSplitCdataSections, gSplitCdataSections);
if (config->canSetParameter(XMLUni::fgDOMWRTDiscardDefaultContent, gDiscardDefaultContent))
config->setParameter(XMLUni::fgDOMWRTDiscardDefaultContent, gDiscardDefaultContent);
if (config->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, gFormatPrettyPrint))
config->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, gFormatPrettyPrint);
theOutput->setByteStream(pFormatTarget);
theSerializer->write(_pDocument, theOutput);
theOutput->release();
}
theSerializer->release();
@@ -1429,7 +1449,59 @@ void ParameterManager::CreateDocument(void)
void ParameterManager::CheckDocument() const
{
if (!_pDocument)
return;
try {
//
// Plug in a format target to receive the resultant
// XML stream from the serializer.
//
// LocalFileFormatTarget prints the resultant XML stream
// to a file once it receives any thing from the serializer.
//
MemBufFormatTarget myFormTarget;
SaveDocument(&myFormTarget);
// Either use the file saved on disk or write the current XML into a buffer in memory
// const char* xmlFile = "...";
MemBufInputSource xmlFile(myFormTarget.getRawBuffer(), myFormTarget.getLen(), "(memory)");
// Either load the XSD file from disk or use the built-in string
// const char* xsdFile = "...";
std::string xsdStr(xmlSchemeString);
MemBufInputSource xsdFile(reinterpret_cast<const XMLByte*>(xsdStr.c_str()), xsdStr.size(), "Parameter.xsd");
// See http://apache-xml-project.6118.n7.nabble.com/validating-xml-with-xsd-schema-td17515.html
//
XercesDOMParser parser;
Grammar* grammar = parser.loadGrammar(xsdFile, Grammar::SchemaGrammarType, true);
if (!grammar) {
Base::Console().Error("Grammar file cannot be loaded.\n");
return;
}
parser.setExternalNoNamespaceSchemaLocation("Parameter.xsd");
//parser.setExitOnFirstFatalError(true);
//parser.setValidationConstraintFatal(true);
parser.cacheGrammarFromParse(true);
parser.setValidationScheme(XercesDOMParser::Val_Auto);
parser.setDoNamespaces(true);
parser.setDoSchema(true);
DOMTreeErrorReporter errHandler;
parser.setErrorHandler(&errHandler);
parser.parse(xmlFile);
if (parser.getErrorCount() > 0) {
Base::Console().Error("Unexpected XML structure detected: %d errors\n", parser.getErrorCount());
}
}
catch (XMLException& e) {
std::cerr << "An error occurred while checking document. Msg is:"
<< std::endl
<< StrX(e.getMessage()) << std::endl;
}
}