• delta3d中,读取自己的xml配置文件。


    最近,项目组让搞一个读取xml配置文件的数据库连接信息的功能。

      一开始准备使用tinyxml,或者rapidxml。没注意delta3d的读取xml信息的类。

      后来发现,delta3d中读取xml的类,是对xecres的一些二次封装,专门读delta3d的地图,里面含有角色代理之类的。

    对于读取自己的数据库连接信息不太方便。就准备用delta3d自带的xecres开源库,自己写一个。

    一开始以为xecres的资料应该很多,后来发现都不太完整,结合网上的一些实例。搞了二天,终于出了一版读取自己xml的一个类。

    写下来,以便记忆。如后来有改善,就不断更新。

    代码如下:头文件:

    #include <xercesc/dom/DOMDocumentType.hpp>
    #include <xercesc/dom/DOMElement.hpp>
    #include <xercesc/dom/DOMImplementation.hpp>
    #include <xercesc/dom/DOMImplementationLS.hpp>
    #include <xercesc/dom/DOMNodeIterator.hpp>
    #include <xercesc/dom/DOMNodeList.hpp>
    #include <xercesc/dom/DOMNamedNodeMap.hpp>
    #include <xercesc/dom/DOMText.hpp>
    #include <xercesc/dom/DOMAttr.hpp>
    #include <xercesc/dom/DOMTreeWalker.hpp>
    #include <xercesc/parsers/XercesDOMParser.hpp>
    #include <xercesc/util/XMLUni.hpp>
    #include <xercesc/framework/XMLFormatter.hpp>
    #include <xercesc/util/XMLString.hpp>
    #include <stdlib.h>
    #include <string>
    #include <vector>
    #include <map>
    #include <stdexcept>
    using namespace std;
    using namespace xercesc;
    class ReadXml
    {
    public:
    ReadXml();
    ~ReadXml();
    void xmlParser(string&) throw(std::runtime_error);
    int loopXMLElement(DOMNode *node);

    private:
    XercesDOMParser *m_DOMXmlParser;
    typedef map<string ,string> DATA_INFORMATION;
    DATA_INFORMATION dataMap;


    };

    实现文件:

    #include <string>
    #include <iostream>
    #include <sstream>
    #include "ReadXML.h"

    ReadXml::ReadXml()
    {
    try
    {
    XMLPlatformUtils::Initialize();//初始化类库

    }
    catch (xercesc::XMLException& excp)
    {
    char* msg = XMLString::transcode(excp.getMessage());
    printf("XML tookit initialization error: %S\n",msg);
    XMLString::release(&msg);
    }
    m_DOMXmlParser = new XercesDOMParser;

    }
    ReadXml::~ReadXml()
    {
    try
    {
    XMLPlatformUtils::Terminate();
    }
    catch(XMLException& excp)
    {
    char* msg = XMLString::transcode(excp.getMessage());
    printf("XML toolkit terminate error: %s\n", msg);
    XMLString::release(&msg);
    }
    }



    void ReadXml::xmlParser(string& xmlFile) throw(std::runtime_error)
    {

    m_DOMXmlParser->setValidationScheme(XercesDOMParser::Val_Auto);//采用Schemal自动验证

    /*设置Parser是否处理xml文档中的名域,如果为true,则Parser增强名域定义的约束和规则。*/
    m_DOMXmlParser->setDoNamespaces( false );

    /*设置Parser处理xml文档中的schema,false就是不处理 */
    m_DOMXmlParser->setDoSchema( false );
    /**/
    m_DOMXmlParser->setLoadExternalDTD( false );
    try
    {
    /*Parser解析器调用parse方法解析XML,安装解析器设置的各种参数,执行Schemal验证,将XML读取到内存,并成为一个DOM树形结构*/
    m_DOMXmlParser->parse(xmlFile.c_str()) ;

    //取得DOM数据
    DOMDocument* xmlDoc = m_DOMXmlParser->getDocument();
    //取得根结点
    DOMElement *pRoot = xmlDoc->getDocumentElement();

    if (!pRoot )
    {
    throw(std::runtime_error( "empty XML document" ));
    }
    //创建一个 walker to 遍历结点
    //DOMNodeFilter::SHOW_ELEMENT显示元素结点,SHOW_TEXT显示文本结点
    DOMTreeWalker* walker = xmlDoc->createTreeWalker(pRoot,DOMNodeFilter::SHOW_ELEMENT,0,true);
    std::cout<<"TreeWalker:\n";

    for (DOMNode *current = walker->nextNode();current!=0;current=walker->nextNode())
    {


    loopXMLElement(current);
    }

    std::cout<<std::endl;
    //创建一个迭代器去遍历结点
    DOMNodeIterator* iterator = xmlDoc->createNodeIterator(pRoot,
    DOMNodeFilter::SHOW_ELEMENT, NULL, true);
    std::cout<< "iterator遍历开始:\n";

    for ( DOMNode * current = iterator->nextNode();
    current != 0; current = iterator->nextNode() )
    {
    string strName = XMLString::transcode(current->getNodeName());
    string strValue = XMLString::transcode((current->getFirstChild())->getNodeValue());
    std::cout <<strName<<strValue<<endl;

    }

    std::cout<< std::endl;
    }
    catch( xercesc::XMLException& excp )
    {
    char* msg = xercesc::XMLString::transcode( excp.getMessage() );
    ostringstream errBuf;
    errBuf << "Error parsing file: " << msg << flush;
    XMLString::release( &msg );
    }

    }
    /**@brief 遍历DOM节点,采用递归算法,遍历该节点下的所有元素极其属性值(该方法主要是用于上面的parse方法的调用)

    * @param 需要遍历的节点

    * @return 0:表示遍历成功,1:表示失败

    */
    int ReadXml::loopXMLElement(DOMNode *node)
    {
    //DOMNode * child;

    if (node->getNodeType() == DOMNode::ELEMENT_NODE) {
    /*XMLString.transcode() 这个方法有多个重载,既可以把 XMLCh * 格式的数据转换成
    char *的数据,也可以把 char * 的数据转换成 XMLCh *, 我们也可以利用这个函数来
    初始化 XMLCh格式类型的数组,比如 XMLCh temp[100];
    XMLString.transcode(“LS”,temp,99);
    用“ LS ”初始化 temp 这个数组的内容。
    */
    //char * nodeName = XMLString::transcode(node->getNodeName());//获取该节点的名称,这里不需要,注释掉
    //std::string strName(nodeName);

    //获取改节点的属性值,作为map中的value
    char * nodeValue = XMLString::transcode((node->getFirstChild())->getNodeValue());
    std::string strValue(nodeValue);

    //如果该节点下有属性,则遍历其属性

    if (node->hasAttributes())
    {

    DOMNamedNodeMap *pAttributes = node->getAttributes();

    const XMLSize_t nSize = pAttributes->getLength();

    //遍历该节点下的所有属性

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

    DOMAttr *pAttributeNode = (DOMAttr*) pAttributes->item(i);
    /* 属性的名字不需要
    char *name = XMLString::transcode(pAttributeNode->getName());
    std::string name_str = name;
    */

    //获取属性值,作为map中的key
    char *attrValue = XMLString::transcode(pAttributeNode->getValue());
    string attr_str = attrValue;

    //将属性值存放到返回的对象中,此处自己构造对象填值
    std::cout<<attrValue<<"="<<strValue<<std::endl;
    /*本map就是用来存储用户登录数据库信息形式如下:
    hostname":192.168.131.202
    */
    dataMap[attrValue]=strValue;

    XMLString::release(&attrValue);//释放资源

    }

    }


    XMLString::release(&nodeValue);

    }

    return 0;
    }
    int main(int argc ,char* argv[])
    {
    ReadXml *xx = new ReadXml();
    string ss = "dbconfig.xml";//添加自己的配置文件。
    xx->xmlParser(ss);
    return 0;
    }

    以上代码,放在VS中,可以直接运行。如有改善,请跟评论,谢谢。

    我的配置文件是如下格式:

    <dbconfig>
    <property name="hostname">192.168.131.202</property>
    <property name="databasename">*****</property>
    <property name="username">****</property>
    <property name="password">****</property>
    <property name="port">***</property>
    </dbconfig>





  • 相关阅读:
    Git:创建远程仓库并推送内容到远程库
    Git中ssh的使用
    Git中的文件上传、修改、撤消修改和删除
    Git的安装和创建版本库
    HTML相关知识点总结
    Android开发--TableLayout的应用
    Java中sql语句的引号问题
    NXOPEN环境配置
    shell小技巧
    查询MySQL锁等待的语句
  • 原文地址:https://www.cnblogs.com/kanego/p/2249817.html
Copyright © 2020-2023  润新知