【问题标题】:Xerces-C validate xml with hardcoded xsdXerces-C 使用硬编码的 xsd 验证 xml
【发布时间】:2019-02-15 22:33:29
【问题描述】:

我正在编写一个库来获取 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_XsdFilename 替换为std::string a_XsdText 之类的东西? 其中std::string a_XsdText 包含架构定义本身,而不是包含架构定义的文件的路径。

【问题讨论】:

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


    【解决方案1】:

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

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

    从文件路径加载 XSD

    Boris Kolpackov 在blog post 中建议应用程序应该自己提供 XSD 架构文件,而不是通过 xsi:schemaLocationxsi:noNamespaceSchemaLocation 查找架构文件> 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

    DOMLSInput 可以像这样在xercesc::MemBufInputSourcexercesc::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 XSDembedded示例(即放在公共域中)演示了如何使用

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

    【讨论】:

      猜你喜欢
      • 2014-03-27
      • 2011-05-31
      • 1970-01-01
      • 1970-01-01
      • 2014-01-16
      • 1970-01-01
      • 1970-01-01
      • 2020-02-26
      • 1970-01-01
      相关资源
      最近更新 更多