Xercesc使用指南

来源:互联网 发布:exchange 更改域名 编辑:程序博客网 时间:2024/06/06 16:03

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文档