Xerces C.docx
《Xerces C.docx》由会员分享,可在线阅读,更多相关《Xerces C.docx(18页珍藏版)》请在冰点文库上搜索。
XercesC
XercesC++解析XML文档
前一阵子学习Xerces-C++用于解析指定格式XML文档。
在这里,把自己的学习经历和大家分享一下,在这里仅仅讲一些入门的知识,希望对大家有所帮助。
Xerces-C++是什么?
Xerces-C++的前身是IBM的XML4C项目。
XML4C和XML4J是两个并列的项目,而XML4J是Xerces-J——Java实现——的前身。
IBM将这两个项目的源代码让与Apache软件基金会(ApacheSoftwareFoundation),他们将其分别改名为Xerces-C++和Xerces-J。
这两个项目是ApacheXML组的核心项目(如果看到的是“Xerces-C”而不是“Xerces-C++”,也是同一个东西,因为这个项目一开始就是用C(译者注:
原文为C++)语言编写的)。
Xerces-C++:
功能介绍
Xerces-C++是一个非常健壮的XML解析器,其提供的两种解析XML文档的方法,DOM和SAX(我是采用DOM方法)。
SAX是一个面向事件的编程API.一个解析引擎消耗XML序列数据,并在发现进来的XML数据的结构时回调应用程序,这些回调称为事件句柄.
与SAX不同,它允许对XML文档进行编辑并保存为一个文件或者流,还允许以编程的方式构建一个XML文档.DOM提供了一个内存中的模型,你可以遍历文档树,删除节点或者嫁接新节点.与解析的SAX事件不同,DOM事件反映出用户与文档的互动以及使用文档的改变.
总的来说,SAX是按行遍历XML文档的,而DOM是先把XML文档生成树,然后遍历DOM树,来解析每个节点.
Xerces-C++:
学习的过程
1、平台选择:
在学习Xerces-C++之前你必须选择一种应用平台,可以是windows、linux、cygwin,以及solaris等系统平台。
在这里,我选用的是RedhatEnterpriseLinuxAS3,选用的Xerces-C++是xerces-c-src_2_7_0.tar.gz,可以从官方网站:
http:
//www.apache.org/直接下载。
2、编译源码
由于我下载下来的是源码,所以需要对其进行编译,否则我们无法加载库文件。
首先进入你的工作目录:
cd/home/olcom/laubo(这是我当前工作目录)
然后解压你的源码包:
tarzxvfxerces-c-src_2_7_0.tar.gz
设置包含源代码的环境变量:
exportXERCESCROOT=/home/olcom/laubo/xerces-c-src_2_7_0
进入目录:
cdxerces-c-src_2_7_0/src/xercesc
运行脚本生成makefile文件:
./runConfigure-plinux-cgcc-xg++-C--prefix=/opt/ApacheXML
选项:
-p为操作系统平台
-cC编译器
-xC++编译器
-c库的配置路径
编译源码:
make
makeinstall
(编译可能要花费你好一会儿,在我的机器上花费大约7分钟的时间,所以要耐心等候)
3、学习类库
因为类库很大,所以刚开始,我并没有选择去分析与阅读类库,我是先在网上了一个比较完整的例子,然后对其进行编译和调试,然后从例子下手去分析类库所提供的接口。
这里,我把自己的程序简化了一下,希望可以作为大家学习的例子。
首先,我们需要定义一种XML文档的样式。
在这里,我们简单的定义一种样式(含有中文),如下:
//sample.xml
xmlversion="1.0"encoding="utf-8"standalone="no"?
>
<国家调查>
china111->江苏
china112->天津
china113->北京
china114->上海
china115->广州
Asia12->韩国
Asia13->日本
Asia14->越南
Asia15->柬埔寨
Asia16->老挝
America21->巴西
America22->阿根廷
America23->智利
America24->墨西哥
America25->巴拉圭
America26->美国
America27->加拿大
Europe31->英国
Europe32->意大利
Europe33->法国
Europe34->德国
Europe35->西班牙
Europe36->匈牙利
THEEND
国家调查>
定义好格式后,我们来看看程序是如何实现对其解析的,程序如下:
CODE:
[Copytoclipboard]
//CXML.h
#ifndefXML_PARSER_HPP
#defineXML_PARSER_HPP
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
usingnamespacestd;
usingnamespacexercesc;
classXMLStringTranslate;
classCXML
{
public:
CXML();
~CXML();
XMLTransService:
:
CodestranServiceCode;
voidxmlParser(string&)throw(std:
:
runtime_error);
private:
XMLStringTranslate*XMLTan;
xercesc:
:
XercesDOMParser*m_DOMXmlParser;//定义解析对象
};
classXMLStringTranslate:
publicXMLFormatTarget
{
public:
XMLStringTranslate(constchar*constencoding);
boolTranslatorUTF8ToChinese(string&strTranslatorMsg);
boolUTF8_2(char*in,intinLen,char*out,intoutLen);
stringtranslate(constXMLCh*constvalue);
constXMLCh*consttranslate(constchar*constvalue);
virtual~XMLStringTranslate();
protected:
XMLFormatter*fFormatter;
XMLCh*fEncodingUsed;
XMLCh*toFill;
char*m_value;
protected:
enumConstants
{
kTmpBufSize=16*1024,
kCharBufSize=16*1024
};
voidclearbuffer();
virtualvoidwriteChars(constXMLByte*consttoWrite
constunsignedintcount
XMLFormatter*constformatter);
};
#endif
//CXML.cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include"CXML.h"
boolXMLStringTranslate:
:
UTF8_2(char*in,intinLen,char*out,intoutLen)//码型转换
{
iconv_tcd=iconv_open("gbk","UTF-8");
//checkcd
if((int)cd==-1)
{
cout<<"iconvisERROR"<returnfalse;
}
char*pin=in,*pout=out;
intinLen_=inLen+1;
intoutLen_=outLen;
iconv(cd,&pin,(size_t*)&inLen_,&pout,(size_t*)&outLen_);
iconv_close(cd);
returntrue;
}
boolXMLStringTranslate:
:
TranslatorUTF8ToChinese(string&strTranslatorMsg)
{
char*pstrSource=const_cast(strTranslatorMsg.c_str());
charpstrDestination[strTranslatorMsg.length()*2+1];//如此处编译出错,可改为char*pstrDestination=newchar[strTranslatorMsg.length()*2+1],但要记住释放
memset(pstrDestination,'\0',strTranslatorMsg.length()*2+1);
if(!
UTF8_2(pstrSource,strTranslatorMsg.length(),pstrDestination,strTranslatorMsg.length()))
returnfalse;
strTranslatorMsg=pstrDestination;
returntrue;
}
CXML:
:
CXML()
{
try
{
//InitializeXerces-C++library
XMLPlatformUtils:
:
Initialize();
}
catch(xercesc:
:
XMLException&excp)
{
char*msg=XMLString:
:
transcode(excp.getMessage());
printf("XMLtoolkitinitializationerror:
%s\n",msg);
XMLString:
:
release(&msg);
}
XMLTan=newXMLStringTranslate("utf-8");
//创建XercesDOMParser对象,用于解析文档
m_DOMXmlParser=newXercesDOMParser;
}
CXML:
:
~CXML()
{
try
{
deleteXMLTan;
XMLPlatformUtils:
:
Terminate();
}
catch(XMLException&excp)
{
char*msg=XMLString:
:
transcode(excp.getMessage());
printf("XMLtoolkitterminateerror:
%s\n",msg);
XMLString:
:
release(&msg);
}
}
voidCXML:
:
xmlParser(string&xmlFile)throw(std:
:
runtime_error)
{
//获取文件信息状态
structstatfileStatus;
intiretStat=stat(xmlFile.c_str(),&fileStatus);
if(iretStat==ENOENT)
throw(std:
:
runtime_error("file_namedoesnotexist,orpathisanemptystring."));
elseif(iretStat==ENOTDIR)
throw(std:
:
runtime_error("Acomponentofthepathisnotadirectory."));
elseif(iretStat==ELOOP)
throw(std:
:
runtime_error("Toomanysymboliclinksencounteredwhiletraversingthepath."));
elseif(iretStat==EACCES)
throw(std:
:
runtime_error("ermissiondenied."));
elseif(iretStat==ENAMETOOLONG)
throw(std:
:
runtime_error("Filecannotberead\n"));
//配置DOMParser
m_DOMXmlParser->setValidationScheme(XercesDOMParser:
:
Val_Auto);
m_DOMXmlParser->setDoNamespaces(false);
m_DOMXmlParser->setDoSchema(false);
m_DOMXmlParser->setLoadExternalDTD(false);
try
{
//调用XercesC++类库提供的解析接口
m_DOMXmlParser->parse(xmlFile.c_str());
//获得DOM树
DOMDocument*xmlDoc=m_DOMXmlParser->getDocument();
DOMElement*pRoot=xmlDoc->getDocumentElement();
if(!
pRoot)
{
throw(std:
:
runtime_error("emptyXMLdocument"));
}
//createawalkertovisitalltextnodes.
/**********************************************
DOMTreeWalker*walker=
xmlDoc->createTreeWalker(pRoot,DOMNodeFilter:
:
SHOW_TEXT,NULL,true);
//usethetreewalkertoprintoutthetextnodes.
std:
:
cout<<"TreeWalker:
\n";
for(DOMNode*current=walker->nextNode();current!
=0;current=walker->nextNode())
{
char*strValue=XMLString:
:
transcode(current->getNodeValue());
std:
:
cout<XMLString:
:
release(&strValue);
}
std:
:
cout<:
endl;
*************************************************/
//createaniteratortovisitalltextnodes.
DOMNodeIterator*iterator=xmlDoc->createNodeIterator(pRoot,
DOMNodeFilter:
:
SHOW_TEXT,NULL,true);
//usethetreewalkertoprintoutthetextnodes.
std:
:
cout<<"iterator:
\n";
for(DOMNode*current=iterator->nextNode();
current!
=0;current=iterator->nextNode())
{
stringstrValue=XMLTan->translate(current->getNodeValue());
XMLTan->TranslatorUTF8ToChinese(strValue);
std:
:
cout<}
std:
:
cout<:
endl;
}
catch(xercesc:
:
XMLException&excp)
{
char*msg=xercesc:
:
XMLString:
:
transcode(excp.getMessage());
ostringstreamerrBuf;
errBuf<<"Errorparsingfile:
"<XMLString:
:
release(&msg);
}
}
XMLStringTranslate:
:
XMLStringTranslate(constchar*constencoding):
fFormatter(0),
m_value(0),fEncodingUsed(0),toFill(0)
{
XMLFormatTarget*myFormTarget=this;
fEncodingUsed=XMLString:
:
transcode(encoding);
fFormatter=newXMLFormatter(fEncodingUsed
myFormTarget
XMLFormatter:
:
NoEscapes
XMLFormatter:
:
UnRep_CharRef);
toFill=newXMLCh[kTmpBufSize];
clearbuffer();
}
XMLStringTranslate:
:
~XMLStringTranslate()
{
if(fFormatter)
deletefFormatter;
if(fEncodingUsed)
delete[]fEncodingUsed;
if(m_value)
free(m_value);
if(toFill)
free(toFill);
fFormatter=0;
fEncodingUsed=0;
m_value=0;
toFill=0;
}
voidXMLStringTranslate:
:
writeChars(constXMLByte*consttoWrite
constunsignedintcount
XMLFormatter*constformatter)
{
if(m_value)
free(m_value);
m_value=0;
m_value=newchar[count+1];
memset(m_value,0,count+1);
memcpy(m_value,(char*)toWrite,count+1);
}
voidXMLStringTranslate:
:
clearbuffer()
{
if(!
toFill)
return;
for(inti=0;itoF