.h
.cpp
.main
- // XmlParser.h: interface for the CXmlParser class.
- //
- //////////////////////////////////////////////////////////////////////
- #if !defined(AFX_XMLPARSER_H__F732A4D4_D91C_4211_B5E5_EA1CFDA0B239__INCLUDED_)
- #define AFX_XMLPARSER_H__F732A4D4_D91C_4211_B5E5_EA1CFDA0B239__INCLUDED_
- #if _MSC_VER > 1000
- #pragma once
- #endif // _MSC_VER > 1000
- #include <string>
- #include <sstream>
- #import <msxml4.dll>// raw_interfaces_only
- #include <msxml.h>
- #include <iostream>
- #include <vector>
- using namespace MSXML2;
- using namespace std;
- class CXmlParser
- {
- public:
- CXmlParser();
- virtual ~CXmlParser();
- BOOL LoadXml(const CString& strXml);
- inline BOOL IsGotaBurst(BYTE src[], size_t len);
- CString GetInfo() const { return m_strInfo; }
- IXMLDOMNodePtr GetFirstChildByID(const IXMLDOMNodePtr& pFather, const CString& strID) const;
- BOOL ParseMessage(const IXMLDOMNodePtr& pChannel);
- BOOL ParseDBMessage(const IXMLDOMNodePtr& pMsg);
- size_t ParseXmlNode(const IXMLDOMNodePtr& pNode);
- BOOL ParseData(BYTE src[], size_t len, const CString& strMsgID);
- BOOL ParseDataBurst(BYTE src[], size_t len, const CString& strChannelID, const CString &strMsgID);
- private:
- IXMLDOMDocumentPtr m_pXmlDoc;
- CString m_strXml;//xml文件名
- BYTE *m_aRawData;//待处理的码流
- size_t m_nDataLength;
- size_t m_nRemaine;
- size_t m_nPos;//处理的码流的位置
- CString m_strSummary;//显示的本消息的summary
- CString m_strInfo;
- vector<size_t> m_vdwData;
- };
- #endif // !defined(AFX_XMLPARSER_H__F732A4D4_D91C_4211_B5E5_EA1CFDA0B239__INCLUDED_)
.cpp
- // XmlParser.cpp: implementation of the CXmlParser class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "zxc.h"
- #include "XmlParser.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- inline BYTE MakeByte(BYTE b1, BYTE b2)
- {//高半字节放在b1,低半字节放在b2
- BYTE b = b1 << 4;
- // b <<= 4;
- b |= b2;
- return b;
- }
- inline WORD MakeWord(BYTE b1, BYTE b2)
- {
- //WORD w = b1;
- //w <<= 8;
- WORD w = b1 << 8;
- w |= b2;
- return w;
- }
- inline DWORD MakeDWord(BYTE b1, BYTE b2, BYTE b3, BYTE b4)
- {
- DWORD d = b1 << 24;
- // d <<= 24;
- d |= (b2 << 16);
- d |= (b3 << 8);
- d |= b4;
- return d;
- }
- DWORD GetBits(BYTE *src, size_t pos, size_t len)
- {
- // if (len > 32) return -1;
- DWORD t;
- BYTE *p = src + pos/8;
- t = MakeDWord(*p, *(p+1), *(p+2), *(p+3));
- // std::cout << "word:" << std::hex << t << std::endl;
- DWORD n = sizeof( t);
- DWORD b = (n<<3) - pos%8 - len;// - 1;
- t >>= b;
- // std::cout << "right shift: " << std::hex << t << std::endl;
- DWORD x = -1;
- // std::cout << "-1/0xff...:" << std::hex << x << std::endl;
- x ^= x << len;
- // std::cout << "mask: " << std::hex << x << std::endl;
- t &= x;
- //src += (pos + len) / 8;
- pos += len;
- return t;
- }
- CXmlParser::CXmlParser()
- {
- m_pXmlDoc = 0;
- ::CoInitialize(NULL);
- HRESULT hr = m_pXmlDoc.CreateInstance(__uuidof(DOMDocument40));
- if(FAILED(hr))
- throw L"failed to create DOM DOC";
- }
- CXmlParser::~CXmlParser()
- {
- // ::CoUninitialize();//有这句会出错,不知道为什么
- }
- BOOL CXmlParser::LoadXml(const CString& strXml)
- {//XML文件中不要加注释,保存为unicode格式,里面不要写汉语
- if (m_strXml == strXml)
- return TRUE;
- m_strXml = strXml;
- return m_pXmlDoc->load(_variant_t(strXml));
- }
- inline BOOL CXmlParser::IsGotaBurst(BYTE src[], size_t len)
- {
- if (len < 3) return FALSE;
- return (*src == 0) && (src[1] == 0) && (src[2] = 0x3c);
- }
- IXMLDOMNodePtr CXmlParser::GetFirstChildByID(const IXMLDOMNodePtr& pFather, const CString &strID) const
- {
- MSXML2::IXMLDOMNodePtr pChild = NULL, pTemp = NULL, pAttr = NULL;
- MSXML2::IXMLDOMNamedNodeMapPtr pAttrs = NULL;
- BSTR text;
- if (pFather == NULL)
- {
- return NULL;
- }
- pChild = pFather->firstChild;
- while (pChild)
- {
- pAttrs = pChild->attributes;
- if (pAttrs == NULL)
- {
- return NULL;
- }
- pAttr = pAttrs->nextNode();
- if (pAttr == NULL)
- return NULL;
- text = pAttr->text;
- if (strID == (LPCTSTR)((_bstr_t)text))
- {
- return pChild;
- }
- pTemp = pChild->nextSibling;
- swap(pChild, pTemp);
- }
- return NULL;
- }
- BOOL CXmlParser::ParseMessage(const IXMLDOMNodePtr& pChannel)
- {
- MSXML2::IXMLDOMNodeListPtr pChildren = NULL;
- MSXML2::IXMLDOMNodePtr pMsg = NULL, pChild = NULL, pAttr1 = NULL, pAttr2 = NULL, pAttr3 = NULL;
- MSXML2::IXMLDOMNamedNodeMapPtr pAttrs = NULL;
- try
- {
- // pMsgList = pChannel->childNodes;
- CString strID;
- strID.Format(L"%d", m_aRawData[0]);
- pMsg = GetFirstChildByID(pChannel, strID);
- if (pMsg == NULL)//没有找到符合ID的消息
- return FALSE;
- m_aRawData++;
- pAttrs = pMsg->attributes;
- pAttrs->nextNode();//忽略第一个属性
- pAttr2 = pAttrs->nextNode();
- BSTR msgName = pAttr2->text;
- m_strInfo += (LPCTSTR)_bstr_t(msgName);// L"/n";
- m_strInfo += L"/n";
- pAttr3 = pAttrs->nextNode();
- BSTR text = pAttr3->text;
- if (wstring(L"true") == (LPCTSTR)(_bstr_t)text)
- m_strSummary = (LPCTSTR)(_bstr_t)msgName;
- pChildren = pMsg->childNodes;
- m_nPos = 0;//important!
- while ((pChild = pChildren->nextNode()) != NULL)
- {
- BSTR s;
- s = pChild->Gettext();
- // wcout << (TCHAR *)(_bstr_t)text << endl;
- size_t len = ParseXmlNode(pChild);
- m_nRemaine -= len;
- }
- // wcout << L"m_strInfo: " << (LPCTSTR)m_strInfo << endl;
- }
- catch(const CString& str)
- {
- wcout << L"error: " << str << endl;
- }
- return TRUE;
- }
- BOOL CXmlParser::ParseDBMessage(const IXMLDOMNodePtr &pMsg)
- {
- MSXML2::IXMLDOMNodeListPtr pChildren = NULL;
- MSXML2::IXMLDOMNodePtr pChild = NULL, pAttr1 = NULL, pAttr2 = NULL, pAttr3 = NULL;
- MSXML2::IXMLDOMNamedNodeMapPtr pAttrs = NULL;
- pAttrs = pMsg->attributes;
- pAttrs->nextNode();//忽略第一个属性
- pAttr2 = pAttrs->nextNode();//消息名
- BSTR msgName = pAttr2->text;
- m_strInfo += (LPCTSTR)_bstr_t(msgName);// L"/n";
- m_strInfo += L"/n";
- pAttr3 = pAttrs->nextNode();
- BSTR text = pAttr3->text;
- if (wstring(L"true") == (LPCTSTR)(_bstr_t)text)
- m_strSummary = (LPCTSTR)(_bstr_t)msgName;
- pChildren = pMsg->childNodes;
- m_nPos = 0;//important!
- while ((pChild = pChildren->nextNode()) != NULL)
- {
- BSTR s;
- s = pChild->Gettext();
- // wcout << (TCHAR *)(_bstr_t)text << endl;
- m_nRemaine -= ParseXmlNode(pChild);
- }
- wcout << L"m_strInfo: " << (LPCTSTR)m_strInfo << endl;
- return FALSE;
- }
- BOOL CXmlParser::ParseData(BYTE src[], size_t len, const CString& strChannelID)
- {
- IXMLDOMNodePtr pRoot = m_pXmlDoc->firstChild;
- IXMLDOMNodePtr pChannel = GetFirstChildByID(pRoot, strChannelID);
- BSTR text = pChannel->baseName;
- // wcout << (TCHAR *)(_bstr_t)text << endl;
- if (*src != len)
- {
- return FALSE;
- }
- m_aRawData = src + 1;
- // m_nPos += 8;
- /*size_t */m_nRemaine = len - 1;
- m_nDataLength = m_nRemaine * 8;
- ParseMessage(pChannel);
- return TRUE;
- }
- size_t CXmlParser::ParseXmlNode(const IXMLDOMNodePtr &pNode)
- {
- size_t nParsed = 0;
- MSXML2::IXMLDOMNodeListPtr pChildren;
- MSXML2::IXMLDOMNodePtr pChild, pAtt1, pAtt2, pAtt3, pAtt4;
- MSXML2::IXMLDOMNamedNodeMapPtr pAttrs;
- BSTR text;
- int d;
- pNode->get_baseName(&text);//得到节点名称
- if (wstring(L"_") == (wchar_t*)((_bstr_t)text))//如果是控制节点
- {
- pNode->get_attributes(&pAttrs);//属性
- pAtt1= pAttrs->nextNode();//第一个属性节点
- pAtt1->get_text(&text);
- long l = _wtoi((_bstr_t)text);//, pos;//所依赖的节点的位置
- d = m_vdwData[m_vdwData.size() + l];
- pAtt2=pAttrs->nextNode();
- pAtt2->get_text(&text);//第二个属性的值
- pNode->get_childNodes(&pChildren);
- if (wstring(L"is") == (wchar_t *)((_bstr_t)text))
- {
- pAtt3 = pAttrs->nextNode();
- pAtt3->get_text(&text);//第三个属性的值
- if (d == _wtoi((_bstr_t)text))
- {//有子项
- pNode->get_childNodes(&pChildren);
- while ((pChild = pChildren->nextNode()) != NULL)
- {//处理每个子项
- nParsed += ParseXmlNode(pChild);
- }
- }
- else
- {
- //没有子项
- }
- }
- else if (wstring(L"has") == (wchar_t *)((_bstr_t)text))
- {
- if (d & _wtoi((_bstr_t)text))
- {//有子项
- pNode->get_childNodes(&pChildren);
- while ((pChild = pChildren->nextNode()) != NULL)
- {
- nParsed += ParseXmlNode(pChild);
- }
- }
- else
- {//没有子项
- }
- }
- else if (wstring(L"len") == (wchar_t *)((_bstr_t)text))
- {
- if (nParsed >= d)
- return nParsed;
- long nChildren;
- pChildren->get_length(&nChildren);
- if (nChildren == 0)
- {//没有子项,则直接输出剩余的数据,并返回
- wostringstream wos;
- //得到长度单位
- pAtt3 = pAttrs->nextNode();
- pAtt3->get_text(&text);
- // wcout << (LPCTSTR)(_bstr_t)text << endl;
- d *= _wtoi((_bstr_t)text);
- //长度单位
- pAtt4 = pAttrs->nextNode();
- wos << (LPCTSTR)(_bstr_t)pAtt4->text << L" = ";
- unsigned long ul;
- for (int i = 0; i < d/8; i++)
- {
- ul = GetBits(m_aRawData, m_nPos, 8);
- wos << hex << L"0x" << ul << L" ";
- m_nPos += 8;
- }
- if (d % 8)
- {
- ul = GetBits(m_aRawData, m_nPos, d % 8);
- wos << hex << L"0x" << ul << endl;
- }
- /*for (int i = 0; i < d; i++)
- {
- ul = GetBits(m_aRawData, m_nPos, 8);
- wos << hex << L"0x" << ul << L" ";
- m_nPos += 8;
- }*/
- m_strInfo += wos.str().c_str();
- m_strInfo += L"/n";
- nParsed += d;
- return nParsed;
- }
- pNode->get_childNodes(&pChildren);
- while ((pChild = pChildren->nextNode()) != NULL)
- {
- nParsed += ParseXmlNode(pChild);
- }
- }
- else if (wstring(L"recur") == (wchar_t *)((_bstr_t)text))
- {
- pAtt3 = pAttrs->nextNode();
- pAtt3->get_text(&text);
- // wcout << (LPCTSTR)(_bstr_t)text << endl;
- d *= _wtoi((_bstr_t)text);
- IXMLDOMNodePtr pTemp, pFirst;
- pFirst = pChildren->nextNode();
- while (d > nParsed)
- {
- // wcout << (LPCTSTR)(_bstr_t)pNode->baseName << endl;
- pChild = pFirst;
- while (pChild != NULL)
- {
- // wcout << (LPCTSTR)(_bstr_t)pChild->baseName << endl;
- nParsed += ParseXmlNode(pChild);
- pTemp = pChild->nextSibling;
- swap(pTemp, pChild);
- }
- }
- }
- return nParsed;
- }
- pNode->get_attributes(&pAttrs);
- pAtt1 = pAttrs->nextNode();
- pAtt1->get_baseName(&text);
- pAtt1->get_text(&text);
- int n = _wtoi((TCHAR *)(_bstr_t)text);
- if (n + m_nPos > m_nDataLength)
- {//如果长度不匹配,则出错
- wcerr << L"error data length" << endl;
- return 0;
- }
- DWORD x = GetBits(m_aRawData, m_nPos, n);
- m_nPos += n;
- nParsed += n;
- pAtt2 = pAttrs->nextNode();
- pAtt2->get_text(&text);//name
- wostringstream ostr;
- ostr << (TCHAR *)((_bstr_t)text) << L" = " << /*m_vdwData[m_vdwData.size() -1]*/ x << endl;//name = dword
- m_strInfo += ostr.str().c_str();
- // wcout << (LPCTSTR)m_strInfo << endl;
- pAtt3 = pAttrs->nextNode();
- if (pAtt3 == NULL)//第3个属性不存在
- return nParsed;
- pAtt3->get_text(&text);//第三个属性为"save"
- if (wstring(L"true") == (LPCTSTR)((_bstr_t)text))
- m_vdwData.push_back(x);
- return nParsed;
- }
- BOOL CXmlParser::ParseDataBurst(BYTE src[], size_t len, const CString &strChannelID, const CString &strMsgID)
- {
- if (!IsGotaBurst(src, len))
- return FALSE;
- IXMLDOMNodePtr pRoot = m_pXmlDoc->firstChild;
- IXMLDOMNodePtr pChannel = GetFirstChildByID(pRoot, strChannelID);
- IXMLDOMNodePtr pMsg = GetFirstChildByID(pChannel, strMsgID);
- if (pMsg == NULL)
- return FALSE;
- // BSTR text = pChannel->baseName;
- m_aRawData = src + 3;
- m_nRemaine = len - 3;
- m_nDataLength = m_nRemaine * 8;
- ParseMessage(pMsg);
- return TRUE;
- }
.main
- // zxc.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include "zxc.h"
- #include "XmlParser.h"
- #include <cmath>
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // The one and only application object
- CWinApp theApp;
- using namespace std;
- int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
- {
- int nRetCode = 0;
- // initialize MFC and print and error on failure
- if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
- {
- // TODO: change error code to suit your needs
- wcerr << _T("Fatal Error: MFC initialization failed") << endl;
- nRetCode = 1;
- }
- else
- {
- // TODO: code your application's behavior here.
- CString strHello;
- strHello.LoadString(IDS_HELLO);
- wcout << (LPCTSTR)strHello << endl;
- }
- /* BYTE ss[] = {0x11, 0x35, 0x20, 0x6E, 0x12, 0x00, 0x01, 0xD8, 0x11, 0x48, 0x0C, 0x33, 0x20, 0x0E, 0xE9, 0x91, 0x1F};
- CXmlParser r;
- r.LoadXml(L"d://aab.xml");
- r.ParseData(ss, 17, L"1007");
- */
- BYTE ds[] = {0x00, 0x00, 0x3c, 0x0c, 0x12, 0x80, 0x09, 0x50, 0x66, 0x26, 0x06, 0x06, 0x06, 0x26, 0x26, 0x20, 0x05, 0x02, 0x01, 0xc0, 0x72, 0x01, 0x20};
- CXmlParser r;
- r.LoadXml(L"d://aab.xml");
- r.ParseDataBurst(ds, 23, L"1008", L"4");
- wcout << L"====================================/n" << (LPCTSTR)r.GetInfo() << endl;
- return nRetCode;
- }