Add an XSD validation scheme and implement ParameterManager::CheckDocument(), function is used in the parameter editor
This commit is contained in:
@@ -89,6 +89,7 @@ generate_from_xml(PlacementPy)
|
||||
generate_from_xml(AxisPy)
|
||||
generate_from_xml(UnitPy)
|
||||
generate_from_xml(QuantityPy)
|
||||
generate_from_any(Parameter.xsd Parameter.inl xmlSchemeString)
|
||||
|
||||
if(SWIG_FOUND)
|
||||
# Create the file swigpyrun.hh and then compare with the file swigpyrun.h.
|
||||
@@ -254,6 +255,7 @@ SET(FreeCADBase_CPP_SRCS
|
||||
Matrix.cpp
|
||||
MatrixPyImp.cpp
|
||||
MemDebug.cpp
|
||||
Parameter.xsd
|
||||
Parameter.cpp
|
||||
ParameterPy.cpp
|
||||
Persistence.cpp
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
57
src/Base/Parameter.xsd
Normal file
57
src/Base/Parameter.xsd
Normal file
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
To verify the user.cfg file against the XSD scheme add the following to the FCParameters element:
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="XSD_FILE_PATH"
|
||||
-->
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="FCParameters">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<!-- This is the top-level parameter group -->
|
||||
<xs:element ref="FCParamGroup" minOccurs="1" maxOccurs="1"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="FCParamGroup">
|
||||
<xs:complexType>
|
||||
<xs:choice maxOccurs="unbounded">
|
||||
<xs:element ref="FCParamGroup" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:element minOccurs="0" maxOccurs="unbounded" name="FCText">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute name="Name" type="xs:string" use="required" />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="unbounded" name="FCBool">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="Name" type="xs:string" use="required" />
|
||||
<xs:attribute name="Value" type="xs:unsignedByte" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="unbounded" name="FCInt">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="Name" type="xs:string" use="required" />
|
||||
<xs:attribute name="Value" type="xs:int" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="unbounded" name="FCFloat">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="Name" type="xs:string" use="required" />
|
||||
<xs:attribute name="Value" type="xs:decimal" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="unbounded" name="FCUInt">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="Name" type="xs:string" use="required" />
|
||||
<xs:attribute name="Value" type="xs:unsignedInt" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:choice>
|
||||
<xs:attribute name="Name" type="xs:string" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -84,6 +84,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>
|
||||
|
||||
@@ -266,6 +266,7 @@ void DlgParameterImp::onChangeParameterSet(int index)
|
||||
if (!rcParMngr)
|
||||
return;
|
||||
|
||||
rcParMngr->CheckDocument();
|
||||
ui->buttonSaveToDisk->setEnabled(rcParMngr->HasSerializer());
|
||||
|
||||
// remove all labels
|
||||
|
||||
Reference in New Issue
Block a user