本文介绍了Xerces-C 使用硬编码的 xsd 验证 xml的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个获取 xml 文件并对其进行解析的库.为了防止用户将无效的 xml 输入到我的应用程序中,我使用 xerces 通过 xsd 验证 xml 文件.

I'm writing a library which takes xml files and parses them. To prevent users from feeding inalid xmls into my application i'm using xerces to validate the xml files via an xsd.

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

However, i only manages to validate against xsd-files. Theoretically an user could just open this file and mess around with it. That's why i would like my xsd to be hardcoded in my library.

不幸的是,我还没有找到使用 XercesC++ 的方法.

Unfortunately i haven't found a way to do this with XercesC++, yet.

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

That's how it is working right now...

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 m_Filename is a member variable holding the path of the xml i validate.

std::string a_XsdFilename 是我验证的 xsd 的路径.

std::string a_XsdFilename is the path to the xsd i validate against.

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

XercesParserErrorHandler inherits from xercesc::ErrorHandler and does error handling.

如何将 std::string a_XsdFilename 替换为 std::string a_XsdText 之类的内容?其中 std::string a_XsdText 包含架构定义本身,而不是包含架构定义的文件的路径.

How can i replace std::string a_XsdFilename with something like std::string a_XsdText?Where std::string a_XsdText contains the schema definition itself instead of a path to a file containing the schema definition.

推荐答案

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

I'll describe three ways of how to hardcode your XSD in your program:

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

Boris Kolpackov 在 中建议博客文章,应用程序应该自己提供 XSD 架构文件,而不是通过 xsi:schemaLocationxsi:noNamespaceSchemaLocation 在XML 文件.

Boris Kolpackov suggests in a blog post that applications should provide the XSD schema files by themselves rather than looking up the schema files through the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attributes found in the XML file.

在博文中有一个链接到 load-grammar-dom ,一个使用 xercesc::DOMLSParser::loadGrammar 函数:

In the blog post there is a link to load-grammar-dom , an example program (put in the public domain) that makes use of the xercesc::DOMLSParser::loadGrammar function:

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

The DOMLSInput could be created with the help of xercesc::MemBufInputSource and xercesc::Wrapper4InputSource like this

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

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

(Adapted somewhat fromhttps://stackoverflow.com/a/15829424/757777 but untested)

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

Included in the software CodeSynthesis XSD the embedded example (that is put in the public domain) demonstrates how to use

xercesc::BinInputStreamxercesc::XMLGrammarPool::deserializeGrammars

加载预编译的 XSD 架构.

to load a precompiled XSD schema.

另请参阅 README.

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

The example contains the program xsdbin that compiles XSD schema files into a binary file.

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:~$

makefileXSD 模式文件由 xsdbin 预编译,结果最终包含在示例可执行文件中.

In the makefile the XSD schema file is precompiled by xsdbin and the result ends up inside the example executable.

这篇关于Xerces-C 使用硬编码的 xsd 验证 xml的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-26 20:02
查看更多