Xercesc使用指南

Xercesc使用指南

作者:Kagula

日期:2009/10/14

读者对象

有在VS2008中,使用C++语言开发的初步经验。

简介:

利用示例,表述Xercesc3.07软件开发包DOM API的使用

摘要:

Xercesc DOM

环境:

[1]VisualStudio2008 with SP1 C++

[2]Xercesc3.01

正文:

第一部分:初始化与Terminate

假设Xercesc安装在D:/SDK/xerces-c-3.0.1-x86-windows-vc-9.0位置

VS2008中设置D:/SDK/xerces-c-3.0.1-x86-windows-vc-9.0/include为头文件路径

VS2008中设置D:/SDK/xerces-c-3.0.1-x86-windows-vc-9.0/lib为库文件路径

复制D:/SDK/xerces-c-3.0.1-x86-windows-vc-9.0/bin位置下的xerces-c_3_0.dll文件和xerces-c_3_0D.dll文件到你项目目录中。

下面的代码为:Xercesc初始化和Terminate的例子

#ifndef _DEBUG

#pragma comment( lib, "xerces-c_3.lib" )

#else

#pragma comment( lib, "xerces-c_3D.lib" )

#endif

#include <xercesc/util/PlatformUtils.hpp>

// Other include files, declarations, and non-Xerces-C++ initializations.

using namespace xercesc;

int main(int argc, char* argv[])

{

try {

XMLPlatformUtils::Initialize();

}

catch (const XMLException& toCatch) {

// Do your failure processing here

return 1;

}

// Do your actual work with Xerces-C++ here.

XMLPlatformUtils::Terminate();

// Other terminations and cleanup.

return 0;

}

第二部分:读取xml文件

本节包含内容:XML文件格式、判断节点类型、取节点名称、取节点值。

XML文件的典型格式,如下

<节点名称1>

<节点名称1-1 属性名1=属性值1 属性名2=属性值2>

<节点名称1-1-1> <!- 节点名为 节点名称1-1-1节点值无 -->

Context <!- 节点名为#text 节点值为Context -->

<!- Context为空,则没有#text节点 -->

</节点名称1-1-1>

</节点名称1-1>

<节点名称 1-2>

</节点名称1-2>

</节点名称1>

参考Domcount例程,得到DOMNode对象

首先判断DOMNode对象的节点类型、然后,对节点内容和值分别存储。

if (static_cast<DOMNode *>(n)->getNodeType() == DOMNode::ELEMENT_NODE)

{

//取节点名称。这里取节点值是没有意义的

char *name = XMLString::transcode(static_cast<DOMNode *>(n)->getNodeName());

pThis->m_strName = name; //存放节点名称

XMLString::release(&name);

//如果本节点有属性,存储属性信息到pThis对象.begin

if(static_cast<DOMNode *>(n)->hasAttributes()) {

// get all the attributes of the node

DOMNamedNodeMap *pAttributes = static_cast<DOMNode *>(n)->getAttributes();

const XMLSize_t nSize = pAttributes->getLength();

std::string strKey,strValue; //用来存放属性名和属性值

for(XMLSize_t i=0;i<nSize;++i) {

DOMAttr *pAttributeNode = (DOMAttr*) pAttributes->item(i);

// get attribute name

char *name = XMLString::transcode(pAttributeNode->getName());

// get attribute type

char *value = XMLString::transcode(pAttributeNode->getValue());

//存放属性名和属性值

strKey = name,strValue=value,pThis->m_mapAttr[strKey]=strValue;

XMLString::release(&name);

XMLString::release(&value);

}

//如果本节点有属性,存储属性信息到pThis对象.end

}

Else if (static_cast<DOMNode *>(n)->getNodeType() == DOMNode::TEXT_NODE)

{

//节点名为#text的节点,可以取其节点值

// omit some code

char *value = XMLString::transcode(static_cast<DOMNode *>(n)->getNodeValue());

// omit some code

}

备注:Xercesc直接支持UTF-8编码的中文。

第三部分:根据内存中的数据产生xml文件

这里通过一个完整的例子来举例

#include <iostream>

#include <xercesc/dom/DOM.hpp>

#include <xercesc/util/XMLString.hpp>

#include <xercesc/framework/LocalFileFormatTarget.hpp>

#pragma comment(lib,"xerces-c_3")

XERCES_CPP_NAMESPACE_USE

using namespace std;

// StrXML class copied from Xerces-2.8 distro.

class StrXML

{

public :

// -----------------------------------------------------------------------

// Constructors and Destructor

// -----------------------------------------------------------------------

StrXML(const char* const toTranscode)

{

// Call the private transcoding method

fLocalForm = XMLString::transcode(toTranscode);

}

~StrXML()

{

XMLString::release(&fLocalForm);

}

// -----------------------------------------------------------------------

// Getter methods

// -----------------------------------------------------------------------

const XMLCh* utf16() const

{

return fLocalForm;

}

private :

// -----------------------------------------------------------------------

// Private data members

//

// fLocalForm

// This is the local code page form of the string.

// -----------------------------------------------------------------------

XMLCh* fLocalForm;

};

int main (int , char **) {

XMLPlatformUtils::Initialize();

DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(StrXML("").utf16());

if (impl == NULL)

throw string("Implementation is NULL in create document.");

// Create the document with one tag

DOMDocument *doc = impl->createDocument(0, StrXML("session").utf16(),

impl->createDocumentType(StrXML("dummy").utf16(),

0, 0));

DOMLSSerializer *theSerializer = ((DOMImplementationLS*)impl)->createLSSerializer();

DOMLSOutput *theOutput = ((DOMImplementationLS*)impl)->createLSOutput();

DOMConfiguration *configuration = theSerializer->getDomConfig();

//a small document tree .begin

DOMElement* root = doc->getDocumentElement();

DOMElement* e1 = doc->createElement(StrXML("FirstElement").utf16());

e1->setAttribute(StrXML("attributeName").utf16(),StrXML("attributeValue").utf16());

root->appendChild(e1);

DOMText* textNode = doc->createTextNode(StrXML("aTextNode").utf16());

e1->appendChild(textNode);

//a small document tree .end

// Have a nice output

if (configuration->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true))

configuration->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);

// Add the declaration?

if (configuration->canSetParameter(XMLUni::fgDOMXMLDeclaration, true))

configuration->setParameter(XMLUni::fgDOMXMLDeclaration, true);

LocalFileFormatTarget *myFormTarget = new LocalFileFormatTarget(StrXML("outfile.xml").utf16());

theOutput->setByteStream(myFormTarget);

if (doc->getDoctype() == NULL) {

cerr << "The doc type is null./n";

exit(-1);

}

theSerializer->write(doc, theOutput);

DOMRange *range = doc->createRange();

range->release();

theOutput->release();

theSerializer->release();

XMLPlatformUtils::Terminate();

}

例子中的range用来释放e1textNode对象的存储空间。

生成a simple document tree部份的代码可以参考

http://xerces.apache.org/xerces-c/program-dom-3.html

文档《Create a small document tree》部份

经过测试,使用OperaIE浏览器打开xml文件,中文可以正常显示,但是使用EditPlus3打开文件,显示乱码,不过这不是本文讨论的重点。

参考:

[1]Xercesc官网

http://xerces.apache.org/xerces-c/program-dom-3.html

[2] 基于XERCES-C编程中的中文(encoding)设置问题的解决方法

http://www.cnitblog.com/silenceburn/archive/2006/04/02/8506.html

内容:采用GB2312编码处理中文,生成XML文档

你可能感兴趣的:(使用)