我尝试使用给定的XSD语法文件验证XML文件。但是现在它始终返回错误no declaration found for element ...
,而且我的XML文件中的每个元素或属性都有错误。
要创建我使用Free online XSD generator的XSD,如果我使用(Validator)[http://www.freeformatter.com/xml-validator-xsd.html]在该XSD中检查我的xml同一个网站,一切都很好。
为什么Xerces会失败?
我使用以下代码进行验证:
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 ....
}
我的XML测试文件是:
<?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>
我使用的XSD是:
<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>
答案 0 :(得分:4)
我在下面的代码中解决了这个问题,我认为setExternalNoNamespaceSchemaLocation
就是诀窍。请注意,我还要为XSD重建absolute
path。
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();
答案 1 :(得分:0)
只需在此处留一些信息,供其他可能因xercesc
遇到麻烦的人使用。
问题作者提供的解决方案很有用,但可能不适用于您的情况。
首先,如果您使用setExternalSchemaLocation
,则不需要loadGrammar
。
第二,如果您的架构处理名称空间,则也尝试setExternalSchemaLocation
。
我的代码:
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());
请注意,没有调用loadGrammar。另外,请注意,xercesc
在您调用之前不会尝试解析模式
xmlParser->parse(...);