CDKEY:D64GG-GXY6T-V6FTR-WCPBB-2YDYB
QMVXY-93XBP-4CQP3-VG9H3-R2Q39
1 配置XERCESC
下载源代码xerces-c-current.tar.gz;
tar xzvf xerces-c-current.tar.gz;
设置XERCESCROOT=解压目录
到XERCESC/src/下,./runConfigure -plinux -cgcc -xg++
gmake
生成lib文件。
到sample下,runConfigure,gmake生成bin下的文件,都是可执行的
2 属性证书的生成
http://hi.baidu.com/cat_june/blog
《把脉VC++》 白乔 左飞
http://xerces.apache.org/xerces-c/program-2.html
http://xerces.apache.org/xerces-c/
http://xerces.apache.org/xerces-c/apiDocs-2/
http://blog.csdn.net/liuchang5/archive/2010/07/30/5776050.aspx //
Xerces-C++ DOM编程指南(一)
2009-04-08 16:48
设计目标
DOM的C++实现是基于阿帕奇推荐的DOM(Apache Recommended DOM C++ binding).
设计目标是为了满足如下需求:
1.降低内存占用率.
2.提高应用程序的性能,特别是那些服务器类型和多线程的应用程序.
3.多处理系统中优异的延展性.
4.比起Java来其风格更像C++
Xerces-C++对DOM Level 3的支持
Xerces-C++2.8.0包含了W3C DOM(文档对象模型)Level 3的部分实现,此实现是实验性的.详情请查看文档DOM Level 3 Support。
使用DOM API
在您的程序代码中访问API
#include <xercesc/dom/DOM.hpp>
在头文件<dom/DOM.hpp>中,包含了DOM API类所需要的全部头文件
类名
DOM类名都以“DOM”为前缀(如果类名本身不以“DOM”开头),例如“DOMNode”,这样是为了防止DOM类名与这样一些类名混淆:一些名称可能已经在应用程序或基于DOM的应用程序所必须链接的类中所使用了。
DOMDocument* myDocument;
DOMNode* aNode;
DOMText* someText;
对象管理
应用程序在C++ DOM中将使用标准C++指针直接访问对象所实现的节点。
思考下面的代码段:
DOMNode* aNode;
DOMNode* docRootNode;
aNode = someDocument->createElement(anElementName);
docRootNode = someDocument->getDocumentElement();
docRootNode->appendChild(aNode);
内存管理
C++ DOM的实现提供了一个release()方法用来释放所有的通过creatxxx工厂方法创建的“孤儿(即现在已不再使用的)”资源,对象销毁而释放的内存资源由C++ DOM的实现进行管理。更详细说明请查看Apache Recommended DOM C++ binding。
使用DOMImplementation::createXXX创建对象
用户必须调用release() 函数来释放由DOMImplementation::createXXX创建的现在已经使用完毕的对象,如DOMBuilder, DOMWriter, DOMDocument, DOMDocumentType。
试图访问已经被释放的对象将导致异常行为。
1.当一个DOMDocument对象被释放后,所有与此对象相关的子对象以及其所拥有的对象(如DOMRange, DOMTreeWalker, DOMNodeIterator或任何孤立的节点)也将被释放。
2.当复制一个DOMDocument对象时,这个复制文档对象不再与其父类文档对(original master document)象有任何联系,并且要显示的释放。
3.当一个DOMDocumentType被插入一个DOMDocument后,这个DOMDocumentType也因此有了一个宿主(owner),当它的宿主(owner document)被释放后它也会被自动释放,此时如果释放这个节点时会产生一个DOMException::INVALID_ACCESS_ERR 异常。
使用DOMDocument::createXXX创建对象
用户应该调用release()函数去显示释放任何一个孤立的节点。当一个孤立节点被释放后,与其相关联的子节点也将被释放。访问一个被释放的节点将导致异常行为。那些孤立的节点最终将会释放,如果现在还没有释放,那么在他们的宿主(owner document)被释放时他们就会被释放。
试图释放一个有父亲的节点将会导致一个DOMException::INVALID_ACCESS_ERR异常。
使用DOMDocumentRange::createRange或者DOMDocumentTraversal::createXXX创建对象
当DOMRange, DOMNodeIterator, DOMTreeWalker使用完毕后,用户应该调用release()函数。访问一个被释放的对象将导致异常行为。那些对象最终将会释放,如果现在还没有释放,那么在他们的宿主(owner document)被释放时他们就会被释放。
如下有一个例子:
//
// Create a small document tree
//
{
XMLCh tempStr[100];
XMLString::transcode("Range", tempStr, 99);
DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(tempStr, 0);
XMLString::transcode("root", tempStr, 99);
DOMDocument* doc = impl->createDocument(0, tempStr, 0);
DOMElement* root = doc->getDocumentElement();
XMLString::transcode("FirstElement", tempStr, 99);
DOMElement* e1 = doc->createElement(tempStr);
root->appendChild(e1);
XMLString::transcode("SecondElement", tempStr, 99);
DOMElement* e2 = doc->createElement(tempStr);
root->appendChild(e2);
XMLString::transcode("aTextNode", tempStr, 99);
DOMText* textNode = doc->createTextNode(tempStr);
e1->appendChild(textNode);
//optionally, call release() to release the resource associated with the range after done
DOMRange* range = doc->createRange();
range->release();
//removedElement is an orphaned node, optionally call release() to release associated resource
DOMElement* removedElement = root->removeChild(e2);
removedElement->release();
// no need to release this returned object which is owned by implementation
XMLString::transcode("*", tempStr, 99);
DOMNodeList* nodeList = doc->getElementsByTagName(tempStr);
// done with the document, must call release() to release the entire document resources
doc->release();
};
字符串型别
C++ DOM使用普通的的无结尾标志的(XMLCh *)UTF-16字符串作为字符串型别,这些(XMLCh*) utf-16 型别的字符串开销极低。
//C++ DOM
const XMLCh* nodeValue = aNode->getNodeValue();
所有的字符串数据都将会保存在内存中直到文档对象被销毁。但是像这些字符串数据在执行过程中必要时有可能会被循环利用(RECYCLED),用户应该使用合适的返回字符串副本作为类型安全的引用.
例如当一个DOMNode被释放后,为其分配的内存资源将会被循环在利用。
XMLCh xfoo[] = {chLatin_f, chLatin_o, chLatin_o, chNull};
// pAttr has node value = "foo"
// fNodeValue has "foo"
pAttr->setNodeValue(xfoo);
const XMLCh* fNodeValue = pAttr->getNodeValue();
// fNodeValue has "foo"
// make a copy of the string for future reference
XMLCh* oldNodeValue = XMLString::replicate(fNodeValue);
// release the node pAttr
pAttr->release()
// other operations
// implementation may have recycled the memory of the pAttr already
// so it's not safe to expect fNodeValue still have "foo"
if (XMLString::compareString(xfoo, fNodeValue))
printf("fNodeValue has some other content/n");
// should use your own safe copy
if (!XMLString::compareString(xfoo, oldNodeValue))
printf("Use your own copy of the oldNodeValue if want to reference the string later/n");
// delete your own replicated string when done
XMLString::release(&oldNodeValue);
如果调用DOMNode::setNodeValue() 去设置一个新节点值,执行时仅仅是简单的重写节点值所占用的内存区域,因此先前的指针现在就会自动的指向新的值。用户应该使用合适的先前所返回的字符串副本作为类型安全的引用.例如:
XMLCh xfoo[] = {chLatin_f, chLatin_o, chLatin_o, chNull};
XMLCh xfee[] = {chLatin_f, chLatin_e, chLatin_e, chNull};
// pAttr has node value = "foo"
pAttr->setNodeValue(xfoo);
const XMLCh* fNodeValue = pAttr->getNodeValue();
// fNodeValue has "foo"
// make a copy of the string for future reference
XMLCh* oldNodeValue = XMLString::replicate(fNodeValue);
// now set pAttr with a new node value "fee"
pAttr->setNodeValue(xfee);
// should not rely on fNodeValue for the old node value, it may not compare
if (XMLString::compareString(xfoo, fNodeValue))
printf("Should not rely on fNodeValue for the old node value/n");
// should use your own safe copy
if (!XMLString::compareString(xfoo, oldNodeValue))
printf("Use your own copy of the oldNodeValue if want to reference the string later/n");
// delete your own replicated string when done
XMLString::release(&oldNodeValue);
这样做是当我们成百上千次调用DOMNode::setNodeValue()时防止内存消耗成等比级数的增长。这一设计容许用户主动的选择返回的字符串应该手动的让它留在内存中还是将这个字符串拷贝到应用程序自己的堆栈中。(这句原文是This design allows users to actively select which returned string should stay in memory by manually copying the string to application's own heap.有些疑问,疑译文是我自己的理解)。
Xerces-C++ DOM编程指南(二)
2009-04-08 16:48
XercesDOMParser
构造XercesDOMParser对象
为了用Xerces-C++解析XML文件,利用DOM,您可以创建XercesDOMParser类的一个实例。下面的例子显示了利用XercesDOMParser创建一个实例所需要的代码:
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#if defined(XERCES_NEW_IOSTREAMS)
#include <iostream>
#else
#include <iostream.h>
#endif
XERCES_CPP_NAMESPACE_USE
int main (int argc, char* args[])
{
try
{
XMLPlatformUtils::Initialize();
}
catch (const XMLException& toCatch)
{
char* message = XMLString::transcode(toCatch.getMessage());
cout << "Error during initialization! :/n"
<< message << "/n";
XMLString::release(&message);
return 1;
}
XercesDOMParser* parser = new XercesDOMParser();
parser->setValidationScheme(XercesDOMParser::Val_Always);
parser->setDoNamespaces(true); // optional
ErrorHandler* errHandler = (ErrorHandler*) new HandlerBase();
parser->setErrorHandler(errHandler);
char* xmlFile = "x1.xml";
try
{
parser->parse(xmlFile);
}
catch (const XMLException& toCatch)
{
char* message = XMLString::transcode(toCatch.getMessage());
cout << "Exception message is: /n"
<< message << "/n";
XMLString::release(&message);
return -1;
}
catch (const DOMException& toCatch)
{
char* message = XMLString::transcode(toCatch.msg);
cout << "Exception message is: /n"
<< message << "/n";
XMLString::release(&message);
return -1;
}
catch (...)
{
cout << "Unexpected Exception /n" ;
return -1;
}
delete parser;
delete errHandler;
return 0;
}
XercesDOMParser所支持的特性
XercesDOMParser的行为依靠下面属性的值。所有下面属性值的设定需要利用"setter"方法(例如 setDoNamespaces) ,因此也要利用对应的的"getter"方法(例如 getDoNamespaces). 下面所呈述的仅仅是对这些支持特性的一个快速预览,更完全详细的内容请查阅API Documentation。
void setCreateEntityReferenceNodes(const bool)
true:在DOM树结构下创建EntityReference节点.这个EntityReference节点以及它的子节点只能被只读访问。
false:不会在DOM树结构下创建EntityReference节点.也没有EntityReference节点被创建, 只有这些节点所对应的全面扩展替代环境将被创建。
default:true
note:这个属性只能影响到DOM树结构中EntityReference节点的性质. 文档将总会包含所有的引用子节点实体。
Xerces-C++的安装配置方法2010年07月16日 星期五 00:40各位同学们,我又开始搞VC6了,很古老的开发工具吧。不过这次是用Xerces解析XML,以前没用过,所以就弄了两天才搞定。现在把Xerces-C++的安装配置方法记录一下,哈哈,有问题请大家指正。
1、下载软件包
上这个网站:http://xerces.apache.org/xerces-c/,现在需要的版本,我下的是xerces-c-src_2_8_0.zip。
2、构件dll
把下载的软件包解压缩了,然后用VC6打开.../xerces-c-src_2_8_0/Projects/Win32/VC6/xerces-all文件夹里的工程。
在编译->活动工程配置中选中相应的工程,我在这里选的是XercesLib - Win32 Release,然后点击确定。
然后按F7构件dll,要花一两分钟的时间,耐心等待。
然后在.../xerces-c-src_2_8_0/Build/Win32/VC6/Release文件夹里就有我们需要的东东了。可以把xerces-c_2_8.dll文件拷贝到自己的工程文件夹里。
3、自己工程的配置
把xerces-c_2_8.dll文件拷贝到自己的工程文件夹里之后,还需要在自己的工程里配置一下。
在工程->设置里:
C/C++标签里,分类选Preprocessor,在附加包含路径里填.../xerces-c-src_2_8_0/src;
Link标签里,分类选Input,在附加库路径里填.../xerces-c-src_2_8_0/Build/Win32/VC6/Release。
在应用的程序头还要加上:
#pragma comment(lib, ".../xerces-c-src_2_8_0/Build/Win32/VC6/Release/xerces-c_2.lib")。
4、测试一下
新建空工程,使用包含语句:#include <xercesc/util/PlatformUtils.hpp>如果编译通过,则安装成功。
可以进行代码编写了。
PS:
Xerces-C++2.8.0的API文档:http://xerces.apache.org/xerces-c/apiDocs-2/index.html
Xerces-C++3.1.1的API文档:http://xerces.apache.org/xerces-c/apiDocs-3 /index.html
Xerces-C++读写XML的实例:http://jobforzd.spaces.live.com/blog/cns!F0FC95ECB11132!120.entry
Xercesc学习笔记[转载]- -
1. 安装
VC6:只需设置Include和Lib路径即可,但我现在必须要在Project中手工加入适当的lib(如xerces-c_2.lib、xerces-c_2D.lib),应该有更好的办法解决,如:
#ifdef _DEBUG
#pragma comment(lib, "xerces-c_2D.lib")
#else
#pragma comment(lib, "xerces-c_2.lib")
#endif
另外,使用Xerces需要xerces-c_2_3_0.dll和xerces-c_2_3_0D.dll两个DLL,很大。不知道有没有办法以Static方法导入类库?
2. 使用
为了使用Xerces,必须在初始化时调用:
XMLPlatformUtils::Initialize();
最后调用:
XMLPlatformUtils::Terminate();
一般说明:
由于XML使用编码集的原因,在Xerces中引入了XMLCh这种数据类型(具体怎么表示????),如果想显示之,可以如下:
XMLCh* pxml;
char* psz = XMLString::transcode( pxml );
cout << psz;
XMLString::release( &psz ); // 这里不能少,否则会内存泄露
为了避免内存泄露,也可以通过包装类的方式来做,如下:
class StrX
{
public :
StrX(const XMLCh* const toTranscode) {
fLocalForm = XMLString::transcode(toTranscode);
}
~StrX() {
XMLString::release(&fLocalForm);
}
const char* localForm() const {
return fLocalForm;
}
private :
char* fLocalForm;
};
// 同时增加该包装的流输出接口:
inline ostream& operator<<(ostream& target, const StrX& toDump) {
target << toDump.localForm();
return target;
}
2.1 使用DOM
一个简单的例子:
// 获得DOMParser
static const XMLCh gLS[] = { chLatin_L, chLatin_S, chNull };
DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(gLS);
DOMBuilder *parser = ( ( DOMImplementationLS* )impl )->createDOMBuilder ( DOMImplementationLS::MODE_SYNCHRONOUS, 0);
/*
另一种获得Parser的方法:
DOMParser* parser = new DOMParser(); // 新建对象
parser->setDoNamespaces( true ); // 设置属性
…
parser->parse( "c://out.xml" ); // 解析
DOMDocument* doc = parser->getDocument(); // 获得DOM文档
…
delete parser; // 由于它不再是由Builder管理的对象,必须delete!
*/
// 解析XML文件
DOMDocument* doc = parser->parseURI( "c://x.xml" );
// 通过DOM操纵XML文件
// 获得XML文件根节点
DOMNode* root = doc->getDocumentElement();
…
// 最后要释放DOM Parser
parser->release();
2.1.1 一些常用类和方法、属性等
DOMNode:结点
bool hasAttributes(); // 是否有属性
DOMNamedNodeMap* getAttributes(); // 获得属性列表
XMLCh* getNodeName(); // 结点名
XMLCh* getNodeValue(); // 结点值
DOMNode* getFirstChild(); // 获得第一个子结点,如果不存在则返回NULL
DOMNode* getNextSibling(); // 获得下一个子结点,如果不存在则返回NULL
NodeType getNodeType(); // 结点类型
enum NodeType {
ELEMENT_NODE = 1,
ATTRIBUTE_NODE = 2,
TEXT_NODE = 3,
CDATA_SECTION_NODE = 4,
ENTITY_REFERENCE_NODE = 5,
ENTITY_NODE = 6,
PROCESSING_INSTRUCTION_NODE = 7,
COMMENT_NODE = 8,
DOCUMENT_NODE = 9,
DOCUMENT_TYPE_NODE = 10,
DOCUMENT_FRAGMENT_NODE = 11,
NOTATION_NODE = 12
};
常见判断:if( n->getNodeType() == DOMNode::ELEMENT_NODE )
// 常用的一种枚举结点的方法:
for(DOMNode* child=root->getFirstChild();child!=NULL;child=child->getNextSibling())…
DOMNamedNodeMap:属性列表
int getLength(); // 属性长度
DOMAttr* item(int i); // 获得第i个属性
DOMAttr:属性
XMLCh* getName(); // 获得属性名
XMLCh* getValue(); // 获得属性值
2.2 使用SAX
SAX是一种基于Event的编程模型,处理方式与DOM完全不一样。
一个例子:
// 使用SAX必须通过一个Handler来进行XML解析,它从HandleBase和XMLFormatTarget继承,通过在适当接口中编写事件处理代码实现基于Event的XML解析。如下:
class SAXPrintHandlers : public HandlerBase, private XMLFormatTarget {
// -----------------------------------------------------------------------
// Constructors
// -----------------------------------------------------------------------
SAXPrintHandlers (
const char* const encodingName
, const XMLFormatter::UnRepFlags unRepFlags
);
~SAXPrintHandlers();
// -----------------------------------------------------------------------
// Implementations of the format target interface
// -----------------------------------------------------------------------
void writeChars (
const XMLByte* const toWrite
);
void writeChars (
const XMLByte* const toWrite
, const unsigned int count
, XMLFormatter* const formatter
);
// -----------------------------------------------------------------------
// Implementations of the SAX DocumentHandler interface
// -----------------------------------------------------------------------
void endDocument();
void endElement(const XMLCh* const name);
void characters(const XMLCh* const chars, const unsigned int length);
void ignorableWhitespace (
const XMLCh* const chars
, const unsigned int length
);
void processingInstruction (
const XMLCh* const target
, const XMLCh* const data
);
void startDocument();
void startElement(const XMLCh* const name, AttributeList& attributes);
// -----------------------------------------------------------------------
// Implementations of the SAX ErrorHandler interface
// -----------------------------------------------------------------------
void warning(const SAXParseException& exception);
void error(const SAXParseException& exception);
void fatalError(const SAXParseException& exception);
// -----------------------------------------------------------------------
// Implementation of the SAX DTDHandler interface
// -----------------------------------------------------------------------
void notationDecl (
const XMLCh* const name
, const XMLCh* const publicId
, const XMLCh* const systemId
);
void unparsedEntityDecl (
const XMLCh* const name
, const XMLCh* const publicId
, const XMLCh* const systemId
, const XMLCh* const notationName
);
}
在主程序中:
static const char* encodingName = "UTF-8"; // 编码集
static XMLFormatter::UnRepFlags unRepFlags = XMLFormatter::UnRep_CharRef;
SAXParser* parser = new SAXParser; // 新建SAX对象
SAXPrintHandlers handler(encodingName, unRepFlags); // 新建Handler对象
parser->setDocumentHandler(&handler); // 设置Handler处理对象
parser->parse(xmlFile); // 解析
delete parser;
具体的使用SAX的方法如何????(需要了解Handler接口方法的含义)
另:
在使用SAX时遇到一个奇怪的问题:
我通过Wizards新建了“An application that support MFC”,结果在里面使用:
SAXParser* parser = new SAXParser;
时总是报错:
TT_SAX.cpp(50) : error C2661: 'new' : no overloaded function takes 3 parameters
结果发现是个古怪的问题:
application support MFC会在主文件中加入:
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
这样new被重定义为DEBUG_NEW,结果总是无法正确的新建SAXParser对象!
解决方法是把上面这段代码注释掉!
或者:加入
#undef new
3. 问题:
Q: 中文处理问题?
A: …
Q: Xerces中存在XMLDouble、XMLFloat类,它们用于把XMLCh*转成double、float,但竟然没有接口把double、float值公开出来!事实上它们都在protected中有fValue表示了正确的值。为什么会这样??????
A:
我想到的一种解决方法:自己再写一个MyXMLDouble、MyXMLFloat类,它们从XMLDouble、XMLFloat中继承,并通过public将fValue外露出来:
class MyXMLDouble : XMLDouble {
public:
double doubleValue() { return fValue; };
};
应该有其它更好的解决方法!