Xerces-C++ SAX2 Schema校验
来源:互联网 发布:靠谱的网络征友 编辑:程序博客网 时间:2024/05/22 15:46
经过几天的研究,终于完成了XML的SAX2 Schema校验。
关于什么是Schema校验,在这里就不废话了,可以去google一下。
下面我就把整个的过程写一下。
借用网上的一些XML文件。
store.xsd文件如下:
<?xml version="1.0" encoding="UTF-8"?><!-- edited with XMLSpy v2011 (http://www.altova.com) by kevin (neuseeker) --><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="store"> <xs:annotation> <xs:documentation>Comment describing your root element</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element ref="goods" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="goods"> <xs:complexType> <xs:sequence> <xs:element ref="id"/> <xs:element ref="price"/> <xs:element ref="vendor"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="id" type="xs:string"/> <xs:element name="price" type="xs:double"/> <xs:element name="vendor" type="xs:string"/></xs:schema>test_good.xml
<?xml version="1.0" encoding="utf-8"?><store> <goods> <id>"0001"</id> <price>3.50</price> <vendor>"xxx奶粉"</vendor> </goods> <goods> <id>"0002"</id> <price>66.00</price> <vendor>"yyy进口奶粉"</vendor> </goods></store>
test_bad.xml
<?xml version="1.0" encoding="utf-8"?><store> <goods> <id>"0001"</id> <price>3.50</price> <vendor>"xxx奶粉"</vendor> <name>"四路奶粉"</name> </goods> <goods> <id>"0002"</id> <price>"66.00"</price> <vendor>"yyy进口奶粉"</vendor> </goods></store>
以以上三个文件为例,进行验证。
代码如下:
OperContentHandler .hpp
#pragma once#if !defined(AFX_A1CONTENTHANDLER_H__E0CFBC18_CCC1_42F3_B0A4_B03331AB9693__INCLUDED_)#define AFX_A1CONTENTHANDLER_H__E0CFBC18_CCC1_42F3_B0A4_B03331AB9693__INCLUDED_#include "stdafx.h"#include <xercesc\sax2\DefaultHandler.hpp>#include <iostream>using namespace std;class OperContentHandler :public DefaultHandler{public:OperContentHandler();virtual ~OperContentHandler();void characters(const XMLCh* const chars, const XMLSize_t length);void endElement(const XMLCh* const uri,const XMLCh* const localname,const XMLCh* const qname);virtual void startElement(const XMLCh* const uri,const XMLCh* const localname,const XMLCh* const qname, const Attributes&attrs); // 继承自default Handle, 用于对错误的处理void error(const SAXParseException& exc){throw exc;}void fatalError(const SAXParseException& exc){throw exc;}void warning(const SAXParseException& exc){throw exc;}wstring goods;};#endif // !defined(AFX_A1CONTENTHANDLER_H__E0CFBC18_CCC1_42F3_B0A4_B03331AB9693__INCLUDED_)
OperContentHandler.cpp
// OperContentHandler.cpp: derived class from SAXContentHandlerImpl#include "stdafx.h"#include "OperContentHandler.hpp"//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////OperContentHandler::OperContentHandler(){}OperContentHandler::~OperContentHandler(){//object destruction is handled by the Release() impl of parent class}void OperContentHandler::startElement(const XMLCh* const uri,const XMLCh* const localname,const XMLCh* const qname, const Attributes&attrs){wstringsNodeName = localname;goods += sNodeName;}void OperContentHandler::endElement( const XMLCh* const uri, const XMLCh* const localname,const XMLCh* const qname ){wstringsNodeName = localname;goods += sNodeName;}void OperContentHandler::characters( const XMLCh* const chars, const XMLSize_t length ){wstring sNodeValue(chars);goods += sNodeValue;}
SAXSchema.cpp文件
// SAXSchema.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include "SAX2XMLReader.hpp"#include "xercesc\sax2\XMLReaderFactory.hpp"#include "OperContentHandler.hpp"#include <stdio.h>#include <string>using namespace std;using namespace xercesc_3_1; void memcpyEx(wchar_t* wDest, int iDsize, wstring src){size_t iCpy = src.length() + 1; // '\0'size_t iMax = iDsize/sizeof(wchar_t);if (src.empty()){memset(wDest, 0, iMax);return;}if (iCpy < iMax){wmemset(wDest, 0, iMax);wmemcpy(wDest, src.c_str(), iCpy);}else{wmemset(wDest, '\0', iMax);iCpy = iMax - 1;wmemcpy(wDest, src.c_str(), iCpy);}}int _tmain(int argc, char* argv[]){wchar_t *xmlPath = L"H:\\WorkSpace\\MarkupTest\\MarkupTest\\test_bad.xml";wchar_t *sxsdPath = L"H:\\WorkSpace\\MarkupTest\\MarkupTest\\store.xsd";OperContentHandler handler;wstring xsdPath(sxsdPath);try{XMLPlatformUtils::Initialize();}catch (...) {return 1;}SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();parser->setFeature(XMLUni::fgSAX2CoreValidation, true);parser->setFeature(XMLUni::fgXercesSchema, true);parser->setFeature(XMLUni::fgXercesValidationErrorAsFatal, true);parser->setFeature(XMLUni::fgXercesContinueAfterFatalError, false);// 当Schema存在命名空间时,使用此部分;其中L"http://www.iec.ch/61850/2003/SCL "为我在试验时的一个命名空间 //wstring xsd = L"http://www.iec.ch/61850/2003/SCL " + xsdPath;//wchar_t xsdCh[400];//memcpyEx(xsdCh, sizeof(xsdCh), xsd);//parser->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation, xsdCh); // 当Schema不存在命名空间时,使用这个方法;在上述的XML中应该使用这个方法来设置模板文件parser->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, sxsdPath); parser->setContentHandler(&handler);parser->setErrorHandler(&handler);try{parser->parse(xmlPath); }catch (const SAXParseException& toCatch) { int iCol = toCatch.getColumnNumber();int iRow = toCatch.getLineNumber();wchar_t cCol[10], cRow[10]; _itow(iCol, cCol, 10); _itow(iRow, cRow, 10);wstring sCol(cCol);wstring sRow(cRow);wstring sMes(toCatch.getMessage()); // 此处将展示错误信息 wstring wValue = L"行:" + sRow + L",列:" + sCol+ L" " + sMes;return 0; }catch (const OutOfMemoryException &ome){wstring sMes(ome.getMessage());return false; }catch (const XMLException &xe){wstring sMes(xe.getMessage());return false; }delete parser;XMLPlatformUtils::Terminate();return 0;}
当进行校验完成后,在wValue的值为:行:7,列:9 no declaration found for element 'name'
上面就是整个Schema校验的校验过程,注意点主要为一下:
一,
在上述的OperContentHandler中,我们重写了继承自DefaultHandler的三个错误处理方法。如果不重写这些方法,OperContentHandler则只是处理了解析过程中和文档内容相关的事件。如果不注册一个错误处理器来处理的话,那么错误事件将不会被报告,而且解析器会出现不可预知的行为。在解析过程中产生的错误被分成了3类,它们分别是warning,error,以及fatalerror,也就是说在ErrorHandler中有这么三个相应的方法来处理这些错误事件。
二,
通过设置fgXercesSchemaExternalNoNameSpaceSchemaLocation或者fgXercesSchemaExternalSchemaLocation属性来设置XSD文件;之前一直以为可以通过loadGrammar()来进行XSD的设置,但是总是不行,可能是理解不到位,不会使用。所以改成了设置属性这种方法。
参考文献:
1,http://www.cnblogs.com/kevin_neu/archive/2013/04/16/3003514.html
2,http://www.codeproject.com/Articles/11085/Parsing-XML-using-a-C-wrapper-for-SAX2
3,http://www.ibm.com/developerworks/cn/xml/x-xsdxerc.html
4,http://xerces.apache.org/xerces-c/program-sax2-3.html
5,https://www.ibm.com/developerworks/cn/xml/x-saxhandle/
- Xerces-C++ SAX2 Schema校验
- 用xerces-c来进行xml schema校验
- xerces-c 解析xml schema
- 采用Xerces C++执行基于schema的XML文档校验
- 关于Xerces-C++执行schema校验相关问题的详细解答
- 用xml Schema对xml进行校验(Xerces-j版本)
- 关于Xerces-C++执行schema校验相关问题的详细解答
- 关于Xerces-C++执行schema校验相关问题的详细解答
- SAX2 driver class org.apache.xerces.parsers.SAXParser not found
- xerces-c编码示例
- 使用schema校验xml
- XMl Schema校验
- xerces-c-2.7下载编译
- 学习xerces-c使用中
- xerces-c和icu编译
- xerces-c-2.7下载地址
- Xerces-C++ 参考
- Xerces-C++ 参考
- grep用法心得
- hadoop-0.23.9安装以及第一个mapreduce测试程序
- C语言中sizeof与strlen区别
- Java 常用正则表达
- workqueue-分析一
- Xerces-C++ SAX2 Schema校验
- 2014暴风影音校招研发类笔试题
- SQL Server 2008 (2008 R2) 清理日志方法
- poj 3207 2-sat 或 染色判二分图
- 面向对象的特征:封装、继承、多态
- 单向链表的常见问题
- Linux系统下忘记MySql密码怎么办?
- Html之Img_图片和文本对齐_图像链接方法_实例
- 中国地图和地方特点介绍