#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
**************************************************************************/