Reputation: 8469
I try to validate XML file using a given XSD grammar file. But for now it always return error saying no declaration found for element ...
and that for each element or attribute I have in my XML file.
To create the XSD i used that Free online XSD generator and if I check my xml within that XSD using the (Validator)[http://www.freeformatter.com/xml-validator-xsd.html] on the same site, everything looks fine.
So why Xerces fails ?
I use the following code to validate:
XercesDOMParser domParser;
if (domParser.loadGrammar(schemaFilePath.c_str(), Grammar::SchemaGrammarType) == NULL)
{
throw Except("couldn't load schema");
}
ParserErrorHandler parserErrorHandler;
domParser.setErrorHandler(&parserErrorHandler);
domParser.setValidationScheme(XercesDOMParser::Val_Always);
domParser.setDoNamespaces(true);
domParser.setDoSchema(true);
domParser.setValidationSchemaFullChecking(true);
domParser.parse(xmlFilePath.c_str());
if(domParser.getErrorCount() != 0)
{
throw Except("Invalid XML vs. XSD: " + parserErrorHandler.getErrors()); //merge a error coming from my interceptor ....
}
My XML test file is:
<?xml version="1.0" encoding="UTF-8" ?>
<schemes signature="9fadde05">
<!-- NOTE: Do not modify this file.
Any modifications will invalidate the signature and result in an invalid file!
This is an example scheme, param_set etc... can be rename / market or / product
-->
<scheme>
<name>test1</name>
<other>test2</other>
</scheme>
<param_set>
<input>
<height min="1060" max="1100" />
<width min="1900" max="1940" />
</input>
</param_set>
</schemes>
And the XSD I use is:
<xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="schemes">
<xs:complexType>
<xs:sequence>
<xs:element name="scheme">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
<xs:element type="xs:string" name="other"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="param_set">
<xs:complexType>
<xs:sequence>
<xs:element name="input">
<xs:complexType>
<xs:sequence>
<xs:element name="height">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:short" name="min"/>
<xs:attribute type="xs:short" name="max"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="width">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:short" name="min"/>
<xs:attribute type="xs:short" name="max"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:string" name="signature"/>
</xs:complexType>
</xs:element>
</xs:schema>
Upvotes: 3
Views: 17926
Reputation: 601
Just leaving some info here for others who may experience some troubles with xercesc
.
The solution provided by the question author is useful, yet may not apply to your case.
First, if you use setExternalSchemaLocation
, you do not need to loadGrammar
.
Second, if your schema handles namespaces, try out setExternalSchemaLocation
as well.
My code:
xmlParser = std::make_unique<xercesc::XercesDOMParser>();
std::string xsdPath = "http://your.namespace.com path/to/schema.xsd";
xmlParser->setValidationScheme(xercesc::XercesDOMParser::Val_Always);
xmlParser->setDoNamespaces(true);
xmlParser->setDoSchema(true);
xmlParser->setValidationSchemaFullChecking(true);
//Finally...
xmlParser->setExternalSchemaLocation(xsdPath.c_str());
Note that there is no call to loadGrammar. Also, note that xercesc
will not attempt to parse the schema until you call
xmlParser->parse(...);
Upvotes: 3
Reputation: 8469
I solve that issue the following code, and I think the setExternalNoNamespaceSchemaLocation
is the trick. Note that I had also to rebuild an absolute
path for the XSD.
XMLPlatformUtils::Initialize();
{
XercesDOMParser domParser;
bfs::path pXSD = absolute(schemaFilePath);
if (domParser.loadGrammar(pXSD.string().c_str(), Grammar::SchemaGrammarType) == NULL)
{
throw Except("couldn't load schema");
}
ParserErrorHandler parserErrorHandler;
domParser.setErrorHandler(&parserErrorHandler);
domParser.setValidationScheme(XercesDOMParser::Val_Always);
domParser.setDoNamespaces(true);
domParser.setDoSchema(true);
domParser.setValidationSchemaFullChecking(true);
domParser.setExternalNoNamespaceSchemaLocation(pXSD.string().c_str());
domParser.parse(xmlFilePath.c_str());
if(domParser.getErrorCount() != 0)
{
throw Except("Invalid XML vs. XSD: " + parserErrorHandler.getErrors()); //merge a error coming from my interceptor ....
}
}
XMLPlatformUtils::Terminate();
Upvotes: 8