Xerces-C使用硬编码的xsd验证xml

时间:2018-09-11 12:08:28

标签: c++ xml xsd xerces xerces-c

我正在编写一个接受xml文件并对其进行解析的库。为了防止用户将inalid xml馈入我的应用程序,我使用xerces通过xsd验证xml文件。

但是,我只设法针对xsd文件进行验证。从理论上讲,用户可以打开该文件并弄乱它。这就是为什么我希望在我的库中对我的xsd进行硬编码。

不幸的是,我还没有找到使用XercesC ++做到这一点的方法。

这就是现在的工作方式...

bool XmlParser::validateXml(std::string a_XsdFilename)
{
    xercesc::XercesDOMParser  domParser;
    if (domParser.loadGrammar(a_XsdFilename.c_str(), xercesc::Grammar::SchemaGrammarType) == NULL)
    {
        throw Exceptions::Parser::XmlSchemaNotReadableException();
    }

    XercesParserErrorHandler parserErrorHandler;

    domParser.setErrorHandler(&parserErrorHandler);
    domParser.setValidationScheme(xercesc::XercesDOMParser::Val_Always);
    domParser.setDoNamespaces(true);
    domParser.setDoSchema(true);
    domParser.setValidationSchemaFullChecking(true);

    domParser.parse(m_Filename.c_str());

    return (domParser.getErrorCount() == 0);

}

std::string m_Filename是保存我验证的xml路径的成员变量。

std::string a_XsdFilename是我验证所依据的xsd的路径。

XercesParserErrorHandler继承自xercesc::ErrorHandler并进行错误处理。

如何用std::string a_XsdFilename之类的东西替换std::string a_XsdText std::string a_XsdText包含架构定义本身,而不是包含架构定义的文件的路径。

1 个答案:

答案 0 :(得分:1)

我将介绍三种在程序中对XSD进行硬编码的方法:

  • 通过从文件路径加载XSD(这是您的示例程序现在所做的事情)
  • 通过从字符串加载XSD(这就是您要的内容)
  • 通过预编译的二进制文件加载XSD

从文件路径加载XSD

Boris Kolpackov在blog post中建议应用程序应自行提供XSD架构文件,而不是通过 xsi:schemaLocation xsi:noNamespaceSchemaLocation < / strong>在XML文件中找到的属性。

博客文章中有一个指向load-grammar-dom的链接,该链接是使用xercesc::DOMLSParser::loadGrammar函数的示例程序(放入公共领域):

user@linux:~$ load-grammar-dom
usage: load-grammar-dom [test.xsd ... ] [test.xml ...]
user@linux:~$ 

从字符串加载XSD

如果您想将XSD文件的内容作为字符串传递,则需要使用另一个重载 xercesc::DOMLSParser::loadGrammar 您通过的地方

const DOMLSInput *source

代替

const char *const systemId

可以像这样在xercesc::MemBufInputSourcexercesc::Wrapper4InputSource的帮助下创建DOMLSInput

xercesc::Wrapper4InputSource source(
    new xercesc::MemBufInputSource(
       (const XMLByte *) (a_XsdText.c_str()),
    a_XsdText.size(),
    "A name");

(改编自 https://stackoverflow.com/a/15829424/757777,但未经测试)

从预编译的二进制文件加载XSD

软件CodeSynthesis XSD中包含的embedded示例(放在公共领域中)演示了如何使用

xercesc::BinInputStreamxercesc::XMLGrammarPool::deserializeGrammars

加载预编译的XSD架构。

另请参阅README

该示例包含程序xsdbin,该程序将XSD模式文件编译为二进制文件。

user@linux:~$ xsdbin --help
Usage: xsdbin [options] <files>
Options:
  --help                 Print usage information and exit.
  --verbose              Print progress information.
  --output-dir <dir>     Write generated files to <dir>.
  --hxx-suffix <sfx>     Header file suffix instead of '-schema.hxx'.
  --cxx-suffix <sfx>     Source file suffix instead of '-schema.cxx'.
  --array-name <name>    Binary data array name.
  --disable-multi-import Disable multiple import support.
user@linux:~$

makefile中,xsdbin预编译了XSD模式文件,结果最终存储在示例可执行文件中。