100分急求支持schema验证的XML类库

showjim 2011-02-23 08:55:13
本来打算用QT的QXmlSchema,可是只要一调用load就会引发异常,可气的是跟进去发现源代码注释说明可能造成崩溃,只好放弃了。
...全文
180 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
showjim 2011-02-25
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 proteas 的回复:]
Xerces&Xalan
[/Quote]
花了两天时间,终于能正常使用了。其间碰到很多问题,希望后来者都顺利。

说明:我的编译环境vs2010,下面选择的项目都是VC7.1。
刚开始下载了Xerces最新版本3.1http://xerces.apache.org/xerces-c/,单独使用没有问题。
由于要用到Xalan 1.1,于是又下了一个http://xml.apache.org/xalan-c/,编译通不过,主要是与Xerces不兼容。
后来发现主页上说要与Xerces 2.7一起用,郁闷的是Xerces主页上的最低版本是2.8,找不到2.7下载。
幸好google到相关下载信息http://dev.firnow.com/course/3_program/c++/cppjs/20071023/79636.html,终于下载了一个Xerces 2.7。
Xerces 2.7的编译使用都正常,可是编译Xalan的时候还是不兼容,可能是编译器与官方期待的不同,出现了很多错误,下面主要说说Xalan的编译。

打开Xalan-C_1_10_0-src\xml-xalan\c\Projects\Win32\VC7.1\Xalan.sln,里面有很多项目,如果编译Release版本,先将编译模式由Debug改为Release。
编译任何一个项目都需要添加路径设置:dll与lib添加路径xerces-c-src_2_7_0\Build\Win32\VC7.1\Release,include添加路径xerces-c-src_2_7_0\src;这两个路径都是相对于Xerces。
先编译Localization,因为AllInOne需要用到它,经编译发错有8处类型转换错误,是由于XMLCh与UTF16Ch的定义不同造成的。
1.ICUResHandler.cpp文件89行,ICUResHandler::characters函数中的m_fStream.write(buffer,j);需要改为m_fStream.write((UTF16Ch*)buffer,j);
2.ICUResHandler.cpp文件150行,ICUResHandler::createHeaderForDataFile函数中的m_fStream.write(m_locale,XMLString::stringLen(m_locale));需要改为m_fStream.write((UTF16Ch*)m_locale,XMLString::stringLen(m_locale));
3.NLSHandler.cpp文件58行,NLSHandler::characters函数中的m_fStream.write(chars,length);需要改为m_fStream.write((UTF16Ch*)chars,length);
4.NLSHandler.cpp文件62行,NLSHandler::characters函数中的m_fStream.writeAsASCII(chars,length);需要改为m_fStream.writeAsASCII((UTF16Ch*)chars,length);
5.SAX2Handler.cpp文件118行,SAX2Handler::startElement函数中的m_fIndexOutputStream.writeAsASCII(val,XMLString::stringLen(val));需要改为m_fIndexOutputStream.writeAsASCII((UTF16Ch*)val,XMLString::stringLen(val));
6.MsgFileOutputStream.cpp文件217行,XalanFileOutputStream::write函数中的UTF16Ch* theUTFString = XMLString::transcode(theString);需要改为UTF16Ch* theUTFString = (UTF16Ch*)XMLString::transcode(theString);
7.MsgFileOutputStream.cpp文件221行,XalanFileOutputStream::write函数中的XMLString::release(&theUTFString);需要改为XMLString::release((XMLCh**)&theUTFString);
8.MsgFileOutputStream.cpp文件226行,XalanFileOutputStream::writeAsASCII函数中的char* szString = XMLString::transcode(theString);需要改为char* szString = XMLString::transcode((XMLCh*)theString);

到这里编译Localization应该能成功了,编译完Localization后编译AllInOne,这里不仅仅要添加Xerces的路径还要添加刚才编译好的Localization的dll与lib路径Xalan-C_1_10_0-src\xml-xalan\c\Build\Win32\VC7.1\Release。
编译AllInOne,有很多类型转换错误,主要是由于Xerces的XMLCh与Xalan的XalanDOMChar定义不同引起的。这次用简单一点的方法,直接修改XalanDOMChar的定义使用其与XMLCH一致。找到Xalan-C_1_10_0-src\xml-xalan\c\src\xalanc\Include\PlatformDefinitions.hpp文件116行,#if defined(XALAN_USE_NATIVE_WCHAR_T)之前添加一行#define XALAN_USE_NATIVE_WCHAR_T 1
还有Xalan-C_1_10_0-src\xml-xalan\c\src\xalanc\XalanTransformer\XalanCAPI.cpp文件515行与516行分别改为
XalanDOMString((XMLCh*)key, XalanMemMgrs::getDefaultXercesMemMgr()),
XalanDOMString((XMLCh*)expression, XalanMemMgrs::getDefaultXercesMemMgr()));

另一个错误是xml-xalan\c\src\xalanc\Include\XalanMemMgrAutoPtr.hpp中的MemMgrAutoPtrData::MemMgrAutoPtrData构造函数用0初始化模板指针引起的。可以定义一个模板函数获取该类型的空指针,如
template<typename valueType> inline static valueType *GetNullPointer() { return (valueType*)NULL; }
然后将XalanMemMgrAutoPtr.hpp文件56行的AutoPtrPairType(0,0)改为AutoPtrPairType(GetNullPointer<MemoryManager>(),GetNullPointer<Type>())

恭喜,现在编译可以通过了,不过另一个悲剧可能将上演了。因为如果你采用vs2010默认的优化方式,在xml-xalan\c\src\xalanc\Include\XalanVector.hpp文件1049行开始的shrinkToSize函数被内联优化成了死循环,当然这不是程序的错误,而是编译器的BUG。将1056至1059行的代码删除或注释
do
{
pop_back();
} while (m_size > theSize);
然后,在原位置添加代码
int start = theSize, end = m_size;
while(start != end) destroy(m_data[start++]);
m_size = theSize;
rendao0563 2011-02-23
  • 打赏
  • 举报
回复
Xerces
昵称很不好取 2011-02-23
  • 打赏
  • 举报
回复
MSXML、Xerces、XML4C
Proteas 2011-02-23
  • 打赏
  • 举报
回复
Xerces&Xalan

65,184

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧