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

标签 c++ xml xsd xerces xerces-c

我正在编写一个库,它获取 xml 文件并解析它们。为了防止用户将无效的 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_XsdText 替换 std::string a_XsdFilename 其中 std::string a_XsdText 包含模式定义本身,而不是包含模式定义的文件的路径。

最佳答案

我将描述如何在程序中对 XSD 进行硬编码的三种方法:

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

从文件路径加载 XSD

Boris Kolpackov 建议 blog post应用程序应自行提供 XSD 架构文件,而不是通过 XML 文件中的 xsi:schemaLocationxsi:noNamespaceSchemaLocation 属性查找架构文件。

在博文中有一个指向 load-grammar-dom 的链接,一个使用 xercesc::DOMLSParser::loadGrammar 的示例程序(置于公共(public)领域)功能:

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::MemBufInputSource 的帮助下创建 DOMLSInput和 xercesc::Wrapper4InputSource像这样

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示例(放在公共(public)域中)演示了如何使用

xercesc::BinInputStreamxercesc::XMLGrammarPool::deserializeGrammars

加载预编译的 XSD 架构。

另见 README .

该示例包含将 XSD 架构文件编译成二进制文件的程序 xsdbin

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 XSD 架构文件由 xsdbin 预编译,结果最终包含在示例可执行文件中。

关于c++ - Xerces-C 使用硬编码 xsd 验证 xml,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52275608/

相关文章:

c++ - WinPcap block 数据包

c++ - 将显示设置更改为重复的 WinAPI 函数

java - 无法合并 Dex - commons apache

java - 使用 jaxb-xjc 生成额外的自定义方法

XML Schema Identity constraints - 我可以在选择器的 XPath 中使用绝对路径吗?

java - xml 解码错误 jaxb 预期元素中存在意外元素

c++ - cygwin:lib 在 vi​​sual studio 2005 中不受支持

c++ - MSVC 2010 模板编译器问题

xml - 事实上,API XML 在多次请求后被阻止

java - 您是否需要自定义适配器来将不同的 subview 添加到 ListView