CXML.cpp

来源:互联网 发布:mac怎么设置新浪邮箱 编辑:程序博客网 时间:2024/04/28 15:09

#include "stdafx.h"

//CXML.cpp
#include <string>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include "CXML.h"

CXML::CXML()
{
 try
 {
  XMLPlatformUtils::Initialize();
 }
 catch(xercesc::XMLException &excp)
 {
  char* msg = XMLString::transcode(excp.getMessage());
  printf("XML toolkit initialization error: %s/n", msg);
  XMLString::release(&msg);
 }  

 //创建 XercesDOMParser 对象,用于解析文档
 m_DOMXmlParser = new XercesDOMParser;

 //成员数据初始化
 m_listText.clear();
 m_listStr.clear();
 m_listCmdTreeNode.clear();
 m_CmdInfoKey.clear();
 m_listOfList.clear();
}

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

void CXML::xmlParser(string& xmlFile,
                     list<list<string> > &listOfList,
      list<string> &listCmdTreeNode,
      list<string> &listText,
      list<CmdInfo> &cmdInfoKey)
throw( std::runtime_error )
{
    //配置DOMParser
 m_DOMXmlParser->setValidationScheme( XercesDOMParser::Val_Auto );
 m_DOMXmlParser->setDoNamespaces( false );
 m_DOMXmlParser->setDoSchema( false );
 m_DOMXmlParser->setLoadExternalDTD( false );

 try
 {
  //调用 Xerces C++ 类库提供的解析接口
  m_DOMXmlParser->parse(xmlFile.c_str()) ;
  //获得DOM树
  xercesc::DOMDocument* xmlDoc = m_DOMXmlParser->getDocument();
  //获得根结点
  DOMElement *pRoot = xmlDoc->getDocumentElement();
  if (!pRoot )
  {
   throw(std::runtime_error( "empty XML document" ));
  }

  // create an iterator to visit all nodes.
  DOMNodeIterator* iterator = xmlDoc->createNodeIterator(pRoot, DOMNodeFilter::SHOW_ALL, NULL, true);
  for (DOMNode * current = iterator->nextNode(); current != 0; current = iterator->nextNode())
  {
   //获得结点类型
   short iShortNodeType = current->getNodeType();

   //结点类型如果是Text域
   if ( iShortNodeType == DOMNode::TEXT_NODE)
   {
    char* pText = XMLString::transcode(current->getTextContent());//获得文本值
    CString cstrTmp(pText);
    cstrTmp.Trim();
    string strTmp = cstrTmp.GetBuffer(0);
    cstrTmp.ReleaseBuffer();
    if (!strTmp.empty())
    {
     m_listText.push_back(strTmp);  //模式,加入到m_listText
     std::cout<<"--"<<strTmp<<endl;
     std::list<CmdInfo>::iterator iter;
     for (iter = m_CmdInfoKey.begin(); iter != m_CmdInfoKey.end(); iter++)
     {
      if (iter->strCmdEnd.empty())
      {
       iter->strCmdEnd = strTmp;
      }
     }
    }
    XMLString::release(&pText); //用完后释放,防止内存泄露
    continue;
   }

   //结点类型如果是ELEMENT
   if (iShortNodeType == DOMNode::ELEMENT_NODE)
   {
    //如果当前结点中含有attribute
    if (current->hasAttributes())
    {
                    //Begin@{  Detail:根据ModeTreeNode划分命令树的结点
     char* pNodeName = XMLString::transcode(current->getNodeName());//获得结点名
     CString cstrNodeName(pNodeName);
     XMLString::release(&pNodeName); //用完后释放,防止内存泄露
     cstrNodeName.Trim();
     string strNodeName = (LPSTR)(LPCTSTR)cstrNodeName;
     if (!strNodeName.empty() && strstr(strNodeName.c_str(), "ModeTreeNode"))
     { 
      std::cout<<": "<<strNodeName<<endl;
      if (!m_listStr.empty())
      {
       m_listOfList.push_back(m_listStr);//把非空m_listStr加入到m_listOfList中去
       m_listStr.clear();
      }
     }
                    //End@}

     DOMNamedNodeMap *pAttrNodeMap;
     pAttrNodeMap = current->getAttributes();
     XMLSize_t len = pAttrNodeMap->getLength();
     for (XMLSize_t iAttrIndex = 0; iAttrIndex < len; iAttrIndex++)
     {
      DOMNode *pNodeTmp = pAttrNodeMap->item(iAttrIndex);
      char* pAttrName = XMLString::transcode(pNodeTmp->getNodeName());//获得属性名
      char* pAttrValue = XMLString::transcode(pNodeTmp->getNodeValue());//获得属性值
      CString cstrTmp(pAttrValue);
      cstrTmp.Trim();
      string strTmp = cstrTmp.GetBuffer(0);
      cstrTmp.ReleaseBuffer();

      //如果是命令,则加入到命令队列中去
      if (strstr(pAttrName, "cmd"))
      {
       if (!strTmp.empty())
       {
        m_listStr.push_back(strTmp); //命令,加入到m_listStr中去
        std::cout<<iAttrIndex<<" : "<<strTmp<<endl;
        CmdInfo cmdInfo;
        cmdInfo.strCmd = strTmp;
        cmdInfo.strCmdEnd = "";
        m_CmdInfoKey.push_back(cmdInfo); //把cmdInfo加入到m_CmdInfoKey中去
       }
      }

      //如果是"版本信息"类的值,则加入到m_listCmdTreeNode中去
      if (!strcmp(pAttrName, "TreeNodeName"))
      {
       if (!strTmp.empty())
       {
        m_listCmdTreeNode.push_back(strTmp);//结点名,加入到m_listCmdTreeNode中去
        std::cout<<"++"<<strTmp<<endl;
       }
      }

      XMLString::release(&pAttrName);  //用完后释放,防止内存泄露
      XMLString::release(&pAttrValue); //用完后释放,防止内存泄露
     }
    }
   }
  }

  // 最后一个结点,把非空m_listStr加入到m_listOfList中去
  if (!m_listStr.empty())
  {
   m_listOfList.push_back(m_listStr);
   m_listStr.clear();
  }
 }
 catch( xercesc::XMLException& excp )
 {
  char* msg = xercesc::XMLString::transcode( excp.getMessage() );
  ostringstream errBuf;
  errBuf << "Error parsing file: " << msg << flush;
  XMLString::release( &msg );
 }
}

void CXML::getCmdXML(list<list<string> > &listOfList,
      list<string> &listCmdTreeNode,
      list<string> &listText,
      list<CmdInfo> &CmdInfoKey)
{
 list<list<string> >::iterator iterLstOfLst;
 for (iterLstOfLst = m_listOfList.begin(); iterLstOfLst != m_listOfList.end(); iterLstOfLst++)
 {
  listOfList.push_back(*iterLstOfLst);
 }

 list<string>::iterator iterLstCmdTN;
 for (iterLstCmdTN = m_listCmdTreeNode.begin(); iterLstCmdTN != m_listCmdTreeNode.end(); iterLstCmdTN++)
 {
  listCmdTreeNode.push_back(*iterLstCmdTN);
 }

 list<string>::iterator iterLstText;
 for (iterLstText = m_listText.begin(); iterLstText != m_listText.end(); iterLstText++)
 {
  listText.push_back(*iterLstText);
 }

 list<CmdInfo>::iterator iterCmdInfo;
 for (iterCmdInfo = m_CmdInfoKey.begin(); iterCmdInfo != m_CmdInfoKey.end(); iterCmdInfo++)
 {
  CmdInfoKey.push_back(*iterCmdInfo);
 }
}

void CXML::printXML(string& xmlFile)
{
 list<list<string> > listOfList;
 list<string> listCmdTreeNode;
 list<string> listText;
 list<CmdInfo> CmdInfoKey;

    xmlParser(xmlFile, listOfList, listCmdTreeNode, listText, CmdInfoKey);

 listOfList.clear();
 listCmdTreeNode.clear();
 listText.clear();
 CmdInfoKey.clear();

 getCmdXML(listOfList, listCmdTreeNode, listText, CmdInfoKey);

 cout<<"----------------------listOfList----------------------"<<endl;
 int i = 0;
 while (!listOfList.empty())
 {
  int j = 0;
  while (!listOfList.front().empty())
  {
   cout<<listOfList.front().front()<<endl;
   listOfList.front().pop_front();
   //cout<<"############"<<j++<<"#############"<<endl;
  }
  listOfList.pop_front();
  cout<<"***************"<<i++<<"***************"<<endl;
 }

 cout<<"--------------------listCmdTreeNode-------------------"<<endl;
 while (!listCmdTreeNode.empty())
 {
  cout<<listCmdTreeNode.front()<<endl;
  listCmdTreeNode.pop_front();
 }

 cout<<"-----------------------listText-----------------------"<<endl;
 while (!listText.empty())
 {
  cout<<listText.front()<<endl;
  listText.pop_front();
 }

 cout<<"-----------------------CmdInfoKey-----------------------"<<endl;
 while (!CmdInfoKey.empty())
 {
  CString strCMDTemp;
  strCMDTemp.Format("%s------%s", CmdInfoKey.front().strCmd.c_str(), CmdInfoKey.front().strCmdEnd.c_str());
        cout<<strCMDTemp<<endl;
  CmdInfoKey.pop_front();
 }
}

void CXML::getLanguageXML(const char* pFilename,
        list<string> &listAttr,
        list<string> &listText)
{
 //配置DOMParser
 m_DOMXmlParser->setValidationScheme( XercesDOMParser::Val_Auto);
 m_DOMXmlParser->setDoNamespaces( false );
 m_DOMXmlParser->setDoSchema( false );
 m_DOMXmlParser->setLoadExternalDTD( false );

 try
 {
  //调用 Xerces C++ 类库提供的解析接口
  m_DOMXmlParser->parse(pFilename) ;
  //获得DOM树
  xercesc::DOMDocument* xmlDoc = m_DOMXmlParser->getDocument();
  //获得根结点
  DOMElement *pRoot = xmlDoc->getDocumentElement();
  if (!pRoot )
  {
   throw(std::runtime_error( "empty XML document" ));
  }

  DOMNodeIterator* iterator = xmlDoc->createNodeIterator(pRoot, DOMNodeFilter::SHOW_ALL, NULL, true);
  for (DOMNode * current = iterator->nextNode(); current != 0; current = iterator->nextNode())
  {
   std::list<CmdInfo>::iterator iter;
   short iShortNodeType = current->getNodeType();
   if ( iShortNodeType == DOMNode::TEXT_NODE)
   {
    char* pText = XMLString::transcode(current->getTextContent());//获得文本值
    CString cstrTmp(pText);
    cstrTmp.Trim();
    string strTmp = (LPSTR)(LPCTSTR)cstrTmp;
    if (!strTmp.empty())
    {
     listText.push_back(strTmp);
    }
    XMLString::release(&pText);
    continue;
   }
   if (iShortNodeType == DOMNode::ELEMENT_NODE)
   {
    if (current->hasAttributes())
    {
     DOMNamedNodeMap *pAttrNodeMap;
     pAttrNodeMap = current->getAttributes();
     XMLSize_t len = pAttrNodeMap->getLength();
     for (XMLSize_t iAttrIndex = 0; iAttrIndex < len; iAttrIndex++)
     {
      DOMNode *pNodeTmp = pAttrNodeMap->item(iAttrIndex);
      char *pAttrValue = XMLString::transcode(pNodeTmp->getNodeValue());//获得属性值
      CString cstrTmp(pAttrValue);
      cstrTmp.Trim();
      string strTmp = (LPSTR)(LPCTSTR)cstrTmp;
      if (!strTmp.empty())
      {
       listAttr.push_back(strTmp); //命令,加入到m_listStr中去
      }
      XMLString::release(&pAttrValue);
     }
    }
   }
  }
 }
 catch( xercesc::XMLException& excp )
 {
  char* msg = xercesc::XMLString::transcode( excp.getMessage() );
  ostringstream errBuf;
  errBuf << "Error parsing file: " << msg << flush;
  XMLString::release( &msg );
 }
}

void CXML::printLanguageXML(const char* pFileName)
{
 list<string> listAttr;
 list<string> listText;

 listAttr.clear();
 listText.clear();
 getLanguageXML(pFileName, listAttr, listText);

 std::map<string, string> mapStrLanguage;
 std::map<string, string>::iterator iterMap;
 mapStrLanguage.clear();
 while (!listAttr.empty() && !listText.empty())
 {
  mapStrLanguage.insert(make_pair(listAttr.front(), listText.front()));
     listAttr.pop_front();
     listText.pop_front();
 }

 for (iterMap = mapStrLanguage.begin(); iterMap != mapStrLanguage.end(); iterMap++)
 {
  cout<<iterMap->first<<"------"<<iterMap->second<<endl;
 }
}

 

 

 

 

 

 

 

 

// create a walker to visit all text nodes.
/**************************************************************************
DOMTreeWalker *walker = xmlDoc->createTreeWalker(pRoot, DOMNodeFilter::SHOW_TEXT, NULL, true);
for (DOMNode *current = walker->nextNode(); current != 0; current = walker->nextNode() )
{
 char *strValue = XMLString::transcode( current->getNodeValue() );
 std::cout <<strValue;
 XMLString::release(&strValue);
}
std::cout << std::endl;
**************************************************************************/
/**************************************************************************
//Begin add   by zhujun 2011/1/14 23:19:11  Detail:
DOMNode *pNode = (DOMNode*)xmlDoc->getDocumentElement();
//DOMElement *pRoot = xmlDoc->getDocumentElement();
// 下面开始遍历这个树的结构
if(pNode)
{
 if (pNode->getNodeType() == DOMNode::ELEMENT_NODE)
 {
  DOMNodeList* nodeList = pNode->getChildNodes();
  unsigned int nListLen = nodeList->getLength();
  for (unsigned int i=0; i<nListLen; ++i)
  {
   DOMNode* nodeTemp = nodeList->item(i);
   if (nodeTemp->getNodeType() == DOMNode::ELEMENT_NODE)
   {
    for (DOMNode* node1=nodeTemp->getFirstChild(); node1!=0; node1=node1->getNextSibling())
    {
     char* name = XMLString::transcode(node1->getNodeName());
     string strTemp = name;
     if (strTemp == "name")   // 这个就是跟 xml 文档中 name 节点匹配
     {
      char* myname=XMLString::transcode(node1->getFirstChild()->getNodeValue());
      cout<<myname<<endl;
     }
    }
   }
   continue;
  }
 }
}
//End   add   2011/1/14 23:19:11
//string strValue = XMLString::transcode(current->getNodeValue());//Text内容
//string strGetNodeName = XMLString::transcode(current->getNodeName());//#text
**************************************************************************/

原创粉丝点击