完善了这个解析类

.h
  1. // XmlParser.h: interface for the CXmlParser class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #if !defined(AFX_XMLPARSER_H__F732A4D4_D91C_4211_B5E5_EA1CFDA0B239__INCLUDED_)
  5. #define AFX_XMLPARSER_H__F732A4D4_D91C_4211_B5E5_EA1CFDA0B239__INCLUDED_
  6. #if _MSC_VER > 1000
  7. #pragma once
  8. #endif // _MSC_VER > 1000
  9. #include <string>
  10. #include <sstream>
  11. #import <msxml4.dll>// raw_interfaces_only
  12. #include <msxml.h>
  13. #include <iostream>
  14. #include <vector>
  15. using namespace MSXML2;
  16. using namespace std;
  17. class CXmlParser  
  18. {
  19. public:
  20.     CXmlParser();
  21.     virtual ~CXmlParser();
  22.     BOOL LoadXml(const CString& strXml);
  23.     inline BOOL IsGotaBurst(BYTE src[], size_t len);
  24.     CString GetInfo() const { return m_strInfo; }
  25.     IXMLDOMNodePtr GetFirstChildByID(const IXMLDOMNodePtr& pFather, const CString& strID) const;
  26.     BOOL ParseMessage(const IXMLDOMNodePtr& pChannel);
  27.     BOOL ParseDBMessage(const IXMLDOMNodePtr& pMsg);
  28.     size_t ParseXmlNode(const IXMLDOMNodePtr& pNode);
  29.     BOOL ParseData(BYTE src[], size_t len, const CString& strMsgID);
  30.     BOOL ParseDataBurst(BYTE src[], size_t len, const CString& strChannelID, const CString &strMsgID);
  31. private:
  32.     IXMLDOMDocumentPtr m_pXmlDoc;
  33.     CString m_strXml;//xml文件名
  34.     BYTE *m_aRawData;//待处理的码流
  35.     size_t m_nDataLength;
  36.     size_t m_nRemaine;
  37.     size_t m_nPos;//处理的码流的位置
  38.     CString m_strSummary;//显示的本消息的summary
  39.     CString m_strInfo;
  40.     vector<size_t> m_vdwData;
  41. };
  42. #endif // !defined(AFX_XMLPARSER_H__F732A4D4_D91C_4211_B5E5_EA1CFDA0B239__INCLUDED_)

.cpp
  1. // XmlParser.cpp: implementation of the CXmlParser class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "zxc.h"
  6. #include "XmlParser.h"
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char THIS_FILE[]=__FILE__;
  10. #define new DEBUG_NEW
  11. #endif
  12. //////////////////////////////////////////////////////////////////////
  13. // Construction/Destruction
  14. //////////////////////////////////////////////////////////////////////
  15. inline BYTE MakeByte(BYTE b1, BYTE b2)
  16. {//高半字节放在b1,低半字节放在b2
  17.     BYTE b = b1 << 4;
  18.     //  b <<= 4;
  19.     b |= b2;
  20.     return b;
  21. }
  22. inline WORD MakeWord(BYTE b1, BYTE b2)
  23. {
  24.     //WORD w = b1;
  25.     //w <<= 8;
  26.     WORD w = b1 << 8;
  27.     w |= b2;
  28.     return w;
  29. }
  30. inline DWORD MakeDWord(BYTE b1, BYTE b2, BYTE b3, BYTE b4)
  31. {
  32.     DWORD d = b1 << 24;
  33.     //  d <<= 24;
  34.     d |= (b2 << 16);
  35.     d |= (b3 << 8);
  36.     d |= b4;
  37.     return d;
  38. }
  39. DWORD GetBits(BYTE *src, size_t pos, size_t len)
  40. {
  41.     //  if (len > 32) return -1;
  42.     DWORD t;
  43.     BYTE *p = src + pos/8;
  44.     t = MakeDWord(*p, *(p+1), *(p+2), *(p+3));
  45.     //  std::cout << "word:" << std::hex << t << std::endl;
  46.     DWORD n = sizeof( t);
  47.     DWORD b =  (n<<3) - pos%8 - len;// - 1;
  48.     t >>= b;
  49.     //  std::cout << "right shift: " << std::hex << t << std::endl;
  50.     DWORD x = -1;
  51.     //  std::cout << "-1/0xff...:" << std::hex << x << std::endl;
  52.     x ^= x << len;
  53.     //  std::cout << "mask: " << std::hex << x << std::endl;
  54.     t &= x;
  55.     //src += (pos + len) / 8;
  56.     pos += len;
  57.     return t;
  58. }
  59. CXmlParser::CXmlParser()
  60. {
  61.     m_pXmlDoc = 0;
  62.     ::CoInitialize(NULL);
  63.     
  64.     HRESULT hr = m_pXmlDoc.CreateInstance(__uuidof(DOMDocument40));
  65.     if(FAILED(hr))
  66.         throw L"failed to create DOM DOC";  
  67. }
  68. CXmlParser::~CXmlParser()
  69. {
  70. //  ::CoUninitialize();//有这句会出错,不知道为什么
  71. }
  72. BOOL CXmlParser::LoadXml(const CString& strXml)
  73. {//XML文件中不要加注释,保存为unicode格式,里面不要写汉语
  74.     if (m_strXml == strXml)
  75.         return TRUE;
  76.     m_strXml = strXml;
  77.     return m_pXmlDoc->load(_variant_t(strXml));
  78. }
  79. inline BOOL CXmlParser::IsGotaBurst(BYTE src[], size_t len)
  80. {
  81.     if (len < 3) return FALSE;
  82.     return (*src == 0) && (src[1] == 0) && (src[2] = 0x3c);
  83. }
  84. IXMLDOMNodePtr CXmlParser::GetFirstChildByID(const IXMLDOMNodePtr& pFather, const CString &strID) const
  85. {
  86.     MSXML2::IXMLDOMNodePtr pChild = NULL, pTemp = NULL, pAttr = NULL;
  87.     MSXML2::IXMLDOMNamedNodeMapPtr pAttrs = NULL;
  88.     BSTR text;
  89.     if (pFather == NULL)
  90.     {
  91.         return NULL;
  92.     }
  93.     pChild = pFather->firstChild;
  94.     while (pChild)
  95.     {
  96.         pAttrs = pChild->attributes;
  97.         if (pAttrs == NULL)
  98.         {
  99.             return NULL;
  100.         }
  101.         pAttr = pAttrs->nextNode();
  102.         if (pAttr == NULL)
  103.             return NULL;
  104.         text = pAttr->text;
  105.         if (strID == (LPCTSTR)((_bstr_t)text))
  106.         {
  107.             return pChild;
  108.         }
  109.         pTemp = pChild->nextSibling;
  110.         swap(pChild, pTemp);
  111.     }
  112.     return NULL;
  113. }
  114. BOOL CXmlParser::ParseMessage(const IXMLDOMNodePtr& pChannel)
  115. {
  116.     MSXML2::IXMLDOMNodeListPtr pChildren = NULL;
  117.     MSXML2::IXMLDOMNodePtr pMsg = NULL, pChild = NULL, pAttr1 = NULL, pAttr2 = NULL, pAttr3 = NULL;
  118.     MSXML2::IXMLDOMNamedNodeMapPtr pAttrs = NULL;
  119.     try
  120.     {
  121. //      pMsgList = pChannel->childNodes;
  122.         CString strID;
  123.         strID.Format(L"%d", m_aRawData[0]);
  124.         pMsg = GetFirstChildByID(pChannel, strID);
  125.         if (pMsg == NULL)//没有找到符合ID的消息
  126.             return FALSE;
  127.         m_aRawData++;
  128.         pAttrs = pMsg->attributes;
  129.         pAttrs->nextNode();//忽略第一个属性
  130.         pAttr2 = pAttrs->nextNode();
  131.         BSTR msgName = pAttr2->text;
  132.         m_strInfo += (LPCTSTR)_bstr_t(msgName);// L"/n";
  133.         m_strInfo += L"/n";
  134.         pAttr3 = pAttrs->nextNode();
  135.         BSTR text = pAttr3->text;
  136.         if (wstring(L"true") == (LPCTSTR)(_bstr_t)text)
  137.             m_strSummary = (LPCTSTR)(_bstr_t)msgName;
  138.         pChildren = pMsg->childNodes;
  139.         m_nPos = 0;//important!
  140.         while ((pChild = pChildren->nextNode()) != NULL)
  141.         {
  142.             BSTR s;
  143.             s = pChild->Gettext();
  144.         //  wcout << (TCHAR *)(_bstr_t)text << endl;
  145.             size_t len = ParseXmlNode(pChild);
  146.             m_nRemaine -= len;
  147.         }
  148. //      wcout << L"m_strInfo: " << (LPCTSTR)m_strInfo << endl;
  149.     }
  150.     catch(const CString& str)
  151.     {
  152.         wcout << L"error: " << str << endl;
  153.     }
  154.     return TRUE;
  155. }
  156. BOOL CXmlParser::ParseDBMessage(const IXMLDOMNodePtr &pMsg)
  157. {
  158.     MSXML2::IXMLDOMNodeListPtr pChildren = NULL;
  159.     MSXML2::IXMLDOMNodePtr pChild = NULL, pAttr1 = NULL, pAttr2 = NULL, pAttr3 = NULL;
  160.     MSXML2::IXMLDOMNamedNodeMapPtr pAttrs = NULL;
  161.     pAttrs = pMsg->attributes;
  162.     pAttrs->nextNode();//忽略第一个属性
  163.     pAttr2 = pAttrs->nextNode();//消息名
  164.     BSTR msgName = pAttr2->text;
  165.     m_strInfo += (LPCTSTR)_bstr_t(msgName);// L"/n";
  166.     m_strInfo += L"/n";
  167.     pAttr3 = pAttrs->nextNode();
  168.     BSTR text = pAttr3->text;
  169.     if (wstring(L"true") == (LPCTSTR)(_bstr_t)text)
  170.         m_strSummary = (LPCTSTR)(_bstr_t)msgName;
  171.     pChildren = pMsg->childNodes;
  172.     m_nPos = 0;//important!
  173.     while ((pChild = pChildren->nextNode()) != NULL)
  174.     {
  175.         BSTR s;
  176.         s = pChild->Gettext();
  177.     //  wcout << (TCHAR *)(_bstr_t)text << endl;
  178.         m_nRemaine -= ParseXmlNode(pChild);
  179.     }
  180.     wcout << L"m_strInfo: " << (LPCTSTR)m_strInfo << endl;
  181.     return FALSE;
  182. }
  183. BOOL CXmlParser::ParseData(BYTE src[], size_t len, const CString& strChannelID)
  184. {
  185.     IXMLDOMNodePtr pRoot = m_pXmlDoc->firstChild;
  186.     IXMLDOMNodePtr pChannel = GetFirstChildByID(pRoot, strChannelID);
  187.     BSTR text = pChannel->baseName;
  188. //  wcout << (TCHAR *)(_bstr_t)text << endl;
  189.     if (*src != len)
  190.     {
  191.         return FALSE;
  192.     }
  193.     m_aRawData = src + 1;
  194. //  m_nPos += 8;
  195.     /*size_t */m_nRemaine = len - 1;
  196.     m_nDataLength = m_nRemaine * 8;
  197.     ParseMessage(pChannel);
  198.     return TRUE;
  199. }
  200. size_t CXmlParser::ParseXmlNode(const IXMLDOMNodePtr &pNode)
  201. {
  202.     size_t nParsed = 0;
  203.     MSXML2::IXMLDOMNodeListPtr pChildren;
  204.     MSXML2::IXMLDOMNodePtr pChild, pAtt1, pAtt2, pAtt3, pAtt4;
  205.     MSXML2::IXMLDOMNamedNodeMapPtr pAttrs;
  206.     BSTR text;
  207.     int d;
  208.     pNode->get_baseName(&text);//得到节点名称
  209.     if (wstring(L"_") == (wchar_t*)((_bstr_t)text))//如果是控制节点
  210.     {
  211.         pNode->get_attributes(&pAttrs);//属性
  212.         pAtt1= pAttrs->nextNode();//第一个属性节点
  213.         pAtt1->get_text(&text);
  214.         long l = _wtoi((_bstr_t)text);//, pos;//所依赖的节点的位置
  215.         d = m_vdwData[m_vdwData.size() + l];
  216.         pAtt2=pAttrs->nextNode();
  217.         pAtt2->get_text(&text);//第二个属性的值
  218.         pNode->get_childNodes(&pChildren);
  219.         
  220.         if (wstring(L"is") == (wchar_t *)((_bstr_t)text))
  221.         {
  222.             pAtt3 = pAttrs->nextNode();
  223.             pAtt3->get_text(&text);//第三个属性的值
  224.             if (d == _wtoi((_bstr_t)text))
  225.             {//有子项
  226.                 pNode->get_childNodes(&pChildren);
  227.                 while ((pChild = pChildren->nextNode()) != NULL)
  228.                 {//处理每个子项
  229.                     nParsed += ParseXmlNode(pChild);
  230.                 }
  231.             }
  232.             else
  233.             {
  234.                 //没有子项
  235.             }
  236.         }
  237.         else if (wstring(L"has") == (wchar_t *)((_bstr_t)text))
  238.         {
  239.             if (d & _wtoi((_bstr_t)text))
  240.             {//有子项
  241.                 pNode->get_childNodes(&pChildren);
  242.                 while ((pChild = pChildren->nextNode()) != NULL)
  243.                 {
  244.                     nParsed += ParseXmlNode(pChild);
  245.                 }
  246.             }
  247.             else
  248.             {//没有子项
  249.             }
  250.         }
  251.         else if (wstring(L"len") == (wchar_t *)((_bstr_t)text))
  252.         {
  253.             if (nParsed >= d)
  254.                 return nParsed;
  255.             long nChildren;
  256.             pChildren->get_length(&nChildren);
  257.             if (nChildren == 0)
  258.             {//没有子项,则直接输出剩余的数据,并返回
  259.                 wostringstream wos;
  260.                 
  261.                 //得到长度单位
  262.                 pAtt3 = pAttrs->nextNode();
  263.                 pAtt3->get_text(&text);
  264. //              wcout << (LPCTSTR)(_bstr_t)text << endl;
  265.                 d *= _wtoi((_bstr_t)text);
  266.                 //长度单位
  267.                 pAtt4 = pAttrs->nextNode();
  268.                 
  269.                 wos << (LPCTSTR)(_bstr_t)pAtt4->text << L" = ";
  270.                 unsigned long ul;
  271.                 for (int i = 0; i < d/8; i++)
  272.                 {
  273.                     ul = GetBits(m_aRawData, m_nPos, 8);
  274.                     wos << hex << L"0x" << ul << L" ";
  275.                     m_nPos += 8;
  276.                 }
  277.                 if (d % 8)
  278.                 {
  279.                     ul = GetBits(m_aRawData, m_nPos, d % 8);
  280.                     wos << hex << L"0x" << ul << endl;
  281.                 }
  282.                 /*for (int i = 0; i < d; i++)
  283.                 {
  284.                     ul = GetBits(m_aRawData, m_nPos, 8);
  285.                     wos << hex << L"0x" << ul << L" ";
  286.                     m_nPos += 8;
  287.                 }*/
  288.                 m_strInfo += wos.str().c_str();
  289.                 m_strInfo += L"/n";
  290.                 nParsed += d;
  291.                 return nParsed;
  292.             }
  293.             pNode->get_childNodes(&pChildren);
  294.             while ((pChild = pChildren->nextNode()) != NULL)
  295.             {
  296.                 nParsed += ParseXmlNode(pChild);
  297.             }
  298.         }
  299.         else if (wstring(L"recur") == (wchar_t *)((_bstr_t)text))
  300.         {
  301.             pAtt3 = pAttrs->nextNode();
  302.             pAtt3->get_text(&text);
  303. //          wcout << (LPCTSTR)(_bstr_t)text << endl;
  304.             d *= _wtoi((_bstr_t)text);
  305.             IXMLDOMNodePtr pTemp, pFirst;
  306.             pFirst = pChildren->nextNode();
  307.             while (d > nParsed)
  308.             {
  309. //              wcout << (LPCTSTR)(_bstr_t)pNode->baseName << endl;
  310.                 pChild = pFirst;
  311.                 while (pChild != NULL)
  312.                 {
  313. //                  wcout << (LPCTSTR)(_bstr_t)pChild->baseName << endl;
  314.                     nParsed += ParseXmlNode(pChild);
  315.                     pTemp = pChild->nextSibling;
  316.                     swap(pTemp, pChild);
  317.                 }
  318.             }
  319.         }
  320.         return nParsed;
  321.     }
  322.     pNode->get_attributes(&pAttrs);
  323.     pAtt1 = pAttrs->nextNode();
  324.     pAtt1->get_baseName(&text);
  325.     pAtt1->get_text(&text);
  326.     int n = _wtoi((TCHAR *)(_bstr_t)text);
  327.     if (n + m_nPos > m_nDataLength)
  328.     {//如果长度不匹配,则出错
  329.         wcerr << L"error data length" << endl;
  330.         return 0;
  331.     }
  332.     DWORD x = GetBits(m_aRawData, m_nPos, n);
  333.     
  334.     m_nPos += n;
  335.     nParsed += n;
  336.     pAtt2 = pAttrs->nextNode();
  337.     pAtt2->get_text(&text);//name
  338.     wostringstream ostr;
  339.     ostr << (TCHAR *)((_bstr_t)text) << L" = " << /*m_vdwData[m_vdwData.size() -1]*/ x << endl;//name = dword
  340.     m_strInfo += ostr.str().c_str();
  341. //  wcout << (LPCTSTR)m_strInfo << endl;
  342.     pAtt3 = pAttrs->nextNode();
  343.     if (pAtt3 == NULL)//第3个属性不存在
  344.         return nParsed;
  345.     pAtt3->get_text(&text);//第三个属性为"save"
  346.     if (wstring(L"true") == (LPCTSTR)((_bstr_t)text))
  347.         m_vdwData.push_back(x);
  348.     return nParsed;
  349. }
  350. BOOL CXmlParser::ParseDataBurst(BYTE src[], size_t len, const CString &strChannelID, const CString &strMsgID)
  351. {
  352.     if (!IsGotaBurst(src, len))
  353.         return FALSE;
  354.     IXMLDOMNodePtr pRoot = m_pXmlDoc->firstChild;
  355.     IXMLDOMNodePtr pChannel = GetFirstChildByID(pRoot, strChannelID);
  356.     IXMLDOMNodePtr pMsg = GetFirstChildByID(pChannel, strMsgID);
  357.     if (pMsg == NULL)
  358.         return FALSE;
  359. //  BSTR text = pChannel->baseName;
  360.     m_aRawData = src + 3;
  361.     m_nRemaine = len - 3;
  362.     m_nDataLength = m_nRemaine * 8;
  363.     ParseMessage(pMsg);
  364.     return TRUE;
  365. }

.main
  1. // zxc.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. #include "zxc.h"
  5. #include "XmlParser.h"
  6. #include <cmath>
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // The one and only application object
  14. CWinApp theApp;
  15. using namespace std;
  16. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  17. {
  18.     int nRetCode = 0;
  19.     
  20.     // initialize MFC and print and error on failure
  21.     if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
  22.     {
  23.         // TODO: change error code to suit your needs
  24.         wcerr << _T("Fatal Error: MFC initialization failed") << endl;
  25.         nRetCode = 1;
  26.     }
  27.     else
  28.     {
  29.         // TODO: code your application's behavior here.
  30.         CString strHello;
  31.         strHello.LoadString(IDS_HELLO);
  32.         wcout << (LPCTSTR)strHello << endl;
  33.     }
  34. /*  BYTE ss[] = {0x11, 0x35, 0x20, 0x6E, 0x12, 0x00, 0x01, 0xD8, 0x11, 0x48, 0x0C, 0x33, 0x20, 0x0E, 0xE9, 0x91, 0x1F};
  35.     CXmlParser r;
  36.     r.LoadXml(L"d://aab.xml");
  37.     r.ParseData(ss, 17, L"1007");
  38. */
  39.     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};
  40.     CXmlParser r;
  41.     r.LoadXml(L"d://aab.xml");
  42.     r.ParseDataBurst(ds, 23, L"1008", L"4");
  43.     wcout << L"====================================/n" << (LPCTSTR)r.GetInfo() << endl;
  44.     
  45.     return nRetCode;
  46. }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值