Xerces-C 使用硬编码 xsd 验证 xml
Xerces-C validate xml with hardcoded xsd
我正在编写一个库,它接受 xml 文件并解析它们。为了防止用户将无效的 xmls 送入我的应用程序,我使用 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 模式文件,而不是通过 xsi:schemaLocation 或 xsi:noNamespaceSchemaLocation 属性在 XML 文件中找到。
在博客post中有一个link到load-grammar-dom , an example program (put in the public domain) that makes use of the 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::MemBufInputSource and xercesc::Wrapper4InputSource 的帮助下像这样创建 DOMLSInput
xercesc::Wrapper4InputSource source(
new xercesc::MemBufInputSource(
(const XMLByte *) (a_XsdText.c_str()),
a_XsdText.size(),
"A name");
(改编自
但未经测试)
从预编译的二进制文件加载 XSD
包含在软件中 CodeSynthesis XSD the embedded 示例(放在 public 域中)演示如何使用
xercesc::BinInputStream 和
xercesc::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 预编译,结果最终包含在示例可执行文件中。
我正在编写一个库,它接受 xml 文件并解析它们。为了防止用户将无效的 xmls 送入我的应用程序,我使用 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 模式文件,而不是通过 xsi:schemaLocation 或 xsi:noNamespaceSchemaLocation 属性在 XML 文件中找到。
在博客post中有一个link到load-grammar-dom , an example program (put in the public domain) that makes use of the 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::MemBufInputSource and xercesc::Wrapper4InputSource 的帮助下像这样创建 DOMLSInput
xercesc::Wrapper4InputSource source(
new xercesc::MemBufInputSource(
(const XMLByte *) (a_XsdText.c_str()),
a_XsdText.size(),
"A name");
(改编自 但未经测试)
从预编译的二进制文件加载 XSD
包含在软件中 CodeSynthesis XSD the embedded 示例(放在 public 域中)演示如何使用
xercesc::BinInputStream 和 xercesc::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 预编译,结果最终包含在示例可执行文件中。