xml终于可以解析了

xml文档
  1. <PAGE_CHANNEL ID="1007">
  2.     <MSG id="53" name="Ptt System Parameter message" color="red">
  3.         <Field length="9" name="PN Length"></Field>
  4.         <Field length="6" name="CONFIG_MSG_SEQ"></Field>
  5.         <Field length="8" name="BS_PTT_REV"></Field>
  6.         <Field length="16" name="DLA_ID"></Field>
  7.         <Field length="1" name="REG_CHECKSUM_REP"></Field>
  8.         <Field length="3" name="PTT_BCAST_INDEX"></Field>
  9.         <Field length="1" name="BroadCast_Call_Para_Inl"></Field>
  10.         <_ de="-1" be="is" dval="1">
  11.             <Field length="1" name="PTT_BroadCast_RPC_Mode"></Field>
  12.             <Field length="4" name="RLGAIN_ADJ"></Field>
  13.             <Field length="3" name="GACH_CHAN"></Field>
  14.             <Field length="3" name="GACH_PWR_CNTL_STEP"></Field>
  15.             <Field length="2" name="GACH_ACCESS_PROBE_SEQ"></Field>
  16.             <Field length="2" name="MAX_RESEND_NUM"></Field>
  17.             <Field length="3" name="TR_LENGTH"></Field>
  18.             <Field length="4" name="PR_LENGTH"></Field>
  19.             <Field length="3" name="SIGNAL_ANSWER_TIMER"></Field>
  20.             <Field length="3" name="SIGNAL_PWRSTEP"></Field>
  21.             <Field length="4" name="hardhandoff_comp"></Field>
  22.             <Field length="4" name="HARDHANDOFF_TIMER"></Field>
  23.             <Field length="3" name="MAX_PTT_SLOT_CYCLE_INDEX"></Field>
  24.             <Field length="1" name="SIGN_SLOT_CYCLE_INDEX"></Field>
  25.             <Field length="1" name="QUICK_ACC_CH_INCL"></Field>
  26.             <_ de="-1" dval="1" be="is">
  27.                 <Field length="4" name="QUICK_ACC_CH_NUM"></Field>
  28.             </_>
  29.             <Field length="3" name="QUICK_MAX_CAP_SZ"></Field>
  30.             <Field length="3" name="QUICK_PAM_SZ"></Field>
  31.             <Field length="2" name="RUM_MODE"></Field>
  32.         </_>
  33.     </MSG>
  34. </PAGE_CHANNEL>
程序代码
xmlreader.cpp
  1. #include "StdAfx.h"
  2. #include "XmlReader.h"
  3. #include <sstream>
  4. using namespace std;
  5. //DWORD GetBits(BYTE src[], size_t pos, size_t len)
  6. DWORD GetBits(BYTE *src, size_t pos, size_t len)
  7. {
  8.     //  if (len > 32) return -1;
  9.     DWORD t;
  10.     BYTE *p = src + pos/8;
  11.     t = MakeDWord(*p, *(p+1), *(p+2), *(p+3));
  12.     //  std::cout << "word:" << std::hex << t << std::endl;
  13.     DWORD n = sizeof( t);
  14.     DWORD b =  (n<<3) - pos%8 - len;// - 1;
  15.     t >>= b;
  16.     //  std::cout << "right shift: " << std::hex << t << std::endl;
  17.     DWORD x = -1;
  18.     //  std::cout << "-1/0xff...:" << std::hex << x << std::endl;
  19.     x ^= x << len;
  20.     //  std::cout << "mask: " << std::hex << x << std::endl;
  21.     t &= x;
  22.     //src += (pos + len) / 8;
  23.     pos += len;
  24.     return t;
  25. }
  26. //////////////////////////////////////////////////
  27. CXmlReader::CXmlReader(void)
  28. {
  29.     m_nPos = 0;
  30. //  m_strRawData = NULL;
  31.     m_bRawData = NULL;
  32. //  m_bRawData = new BYTE[]{0x11, 0x35, 0x20, 0x6E, 0x12, 0x00, 0x01, 0xD8, 0x11, 0x48, 0x0C, 0x33, 0x20, 0x0E, 0xE9, 0x91, 0x1F};
  33. }
  34. CXmlReader::CXmlReader(BYTE x[])
  35. {
  36.     m_bRawData = x;
  37. }
  38. CXmlReader::~CXmlReader(void)
  39. {
  40.     delete[] m_bRawData;
  41.     m_bRawData = NULL;
  42. }
  43. /////////////////////////////////////////////////////
  44. //类似于atoi,返回读到的字符的位数
  45. size_t CXmlReader::GetNumber(TCHAR *strCode, int *num)
  46. {//此函数暂时先不用
  47.     //assert(len >= 0 && len < strCode.size());
  48.     int i = 0, j = 0;
  49.     TCHAR *t = strCode;
  50.     if (*t == L'-')
  51.         t++;
  52.     while (*t >=L'0' && *t <= L'9')
  53.     {
  54.         i *= 10;
  55.         i += (*t++ - L'0');
  56.         j++;
  57.     }
  58.     //注意:下一位要么没有,要么是 L'/',否则程序会挂掉
  59.     if (*strCode == L'-')
  60.     {
  61.         i = -i;
  62.     }
  63.     *num = i;
  64.     return j;
  65. }
  66. //rawData:接收到的数据流
  67. int CXmlReader::ParseData(BYTE rawData[], size_t len, MSXML2::IXMLDOMDocumentPtr pDoc)
  68. {
  69.     //if (rawData[0] != len)//rawData是第一位是其长度
  70.     //{
  71.     //  return -1;//数据长度不对,故返回错误
  72.     //}
  73.     MSXML2::IXMLDOMNodeListPtr pNodeList = NULL, pMsgList = NULL, pChildren = NULL;
  74.     MSXML2::IXMLDOMNodePtr pNode = NULL, pMsg = NULL, pAttr1 = NULL, pAttr2 = NULL, pAttr3 = NULL, pChild = NULL;
  75.     MSXML2::IXMLDOMNamedNodeMapPtr pAttrs = NULL;
  76. //  ostringstream ostr;
  77.     //ostr << "_" << rawData[0];
  78. //  ostr <<dec << rawData[0];
  79. //  string str = ostr.str();
  80.     BSTR text;
  81. //  pDoc->getElementsByTagName(_bstr_t(L"page"), &pNodeList);
  82. //  pNodeList->nextNode(&pNode);//为什么得不到 page结点??
  83.     try
  84.     {
  85.         pDoc->get_firstChild(&pNode);
  86.         pNode->get_childNodes(&pMsgList);//msg节点
  87.         while(pMsgList->nextNode(&pMsg), pMsg)
  88.         {
  89.             pMsg->get_attributes(&pAttrs);
  90.             pAttrs->nextNode(&pAttr1);//id
  91.             pAttr1->get_text(&text);
  92.             //cout << ostr.str() << " == " << (_bstr_t)text << endl;
  93.             //cout << (int)rawData[0] <<" == " << _wtoi((TCHAR *)((_bstr_t)text))<<"XXXXXX" << endl;
  94.             //if (ostr.str() == (char *)((_bstr_t)text))
  95.             if ((int)rawData[0] == _wtoi((TCHAR *)((_bstr_t)text)))
  96.             {
  97.                 pAttrs->nextNode(&pAttr2);
  98.                 BSTR msgName;
  99.                 pAttr2->get_text(&msgName);
  100.                 m_strInfo += _bstr_t(msgName);
  101.                 m_strInfo += L"/n";
  102.                 pMsg->get_childNodes(&pChildren);
  103.                 m_nPos = 0;//important!
  104.                 while (pChildren->nextNode(&pChild), pChild)
  105.                 {
  106.                     ParseDoc(rawData + 1, len - 1, pChild);
  107.                 }
  108.                 //ParseDoc(rawData + 1, len-1, pMsg);
  109.                 wcout << "m_strInfo: " << m_strInfo.c_str() << endl;
  110.                 break;
  111.             }
  112.         }
  113.     }
  114.     catch (string str)
  115.     {
  116.         std::cout << str << std::endl;
  117.     }
  118.     catch(...)
  119.     {
  120.         std::cout << "error" << std::endl;
  121.     }
  122.     
  123.     return 0;
  124. }
  125. //strfilename: xml文件名
  126. int CXmlReader::ParseData(BYTE rawData[], size_t len, const wstring& strfilename)
  127. {
  128.     if (rawData[0] != len)
  129.     {
  130.         return FALSE;
  131.     }
  132.     MSXML2::IXMLDOMDocument2Ptr pDoc;
  133.     try
  134.     {
  135.         HRESULT hr = CoCreateInstance(CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER, MSXML2::IID_IXMLDOMDocument, (void**)&pDoc);
  136.         if (FAILED(hr))
  137.             throw "failed to create pDoc";
  138.         VARIANT_BOOL bIsSuccessful;
  139.         _variant_t v1(strfilename.c_str());
  140.         hr = pDoc->load(v1, &bIsSuccessful);
  141.         if (FAILED(hr))
  142.             throw "failed to create pDoc";
  143.         return ParseData(rawData+1, len-1, pDoc);
  144.     }
  145.     catch(...)
  146.     {
  147.         cerr << "load file error" << endl;
  148.         return -1;
  149.     }
  150. }
  151. //递归处理xml文档,根据xml中的信息来解析数据流。控制点决定了子节点是否显示,控制点一般会回探前向节点(<比如其>父节点)
  152. int CXmlReader::ParseDoc(BYTE raw[], size_t len, MSXML2::IXMLDOMNodePtr pNode)
  153. {//节点分两种情况,一本身没有占空间的点(控制点,如_,没有length属性),二占空间的点(有length属性)
  154.     MSXML2::IXMLDOMNodeListPtr pChildren;//, pChild, pNode;
  155.     MSXML2::IXMLDOMNodePtr pChild, pField, pParentAtt, pPrevNode, pAtt1, pAtt2, pAtt3;
  156.     MSXML2::IXMLDOMNamedNodeMapPtr pAttrs, pParentAttrs;
  157.     BSTR text;
  158.     DWORD d;
  159.     pNode->get_baseName(&text);//得到节点名称
  160.     //if (wstring(L"MSG") == (wchar_t*)((_bstr_t)text))
  161.     //{//直接处理其子结点
  162.     //  pNode->get_childNodes(&pChildren);
  163.     //  while (pChildren->nextNode(&pChild), pChild)
  164.     //  {
  165.     //      ParseDoc(raw, len, pChild);
  166.     //  }
  167.     //}
  168.     if (wstring(L"_") == (wchar_t*)((_bstr_t)text))//如果是控制节点
  169.     {
  170. //      pNode->get_previousSibling(&pNode);//上一个兄弟节点//没什么用啊
  171.         pNode->get_attributes(&pAttrs);//属性
  172.         pAttrs->nextNode(&pAtt1);//第一个属性:所依赖的节点
  173.         pAtt1->get_text(&text);
  174. //      pNode->get_baseName(&text);
  175.         long l = _wtoi((_bstr_t)text);//, pos;//所依赖的节点的位置
  176. //      d = GetBits(m_bRawData, m_nPos-l, l);//回退,得到所依赖的节点的值
  177.         d = m_vdwData[m_vdwData.size() + l];
  178.         //pNode->get_nextSibling(&pNode);//本节点
  179.         //pNode->get_attributes(&pAttrs);
  180.         //pAttrs->nextNode(&pField);
  181.         //pField->get_nextSibling(&pField);
  182.         pAttrs->nextNode(&pAtt2);
  183.         pAtt2->get_text(&text);//第二个属性的值
  184. //      BSTR text1;
  185.         //pField->get_baseName(&text1);
  186.         if (wstring(L"is") == (wchar_t *)((_bstr_t)text))
  187.         {
  188.             pAttrs->nextNode(&pAtt3);
  189.             pAtt3->get_text(&text);//第三个属性的值
  190.             if (d == _wtoi((_bstr_t)text))
  191.             {//有子项
  192.                 pNode->get_childNodes(&pChildren);
  193.                 while (pChildren->nextNode(&pChild), pChild)
  194.                 {//处理每个子项
  195.                     ParseDoc(raw, len, pChild);
  196.                 }
  197.             }
  198.             else
  199.             {
  200.                 //没有子项
  201.             }
  202.         }
  203.         else if (wstring(L"has") == (wchar_t *)((_bstr_t)text))
  204.         {
  205.             if (d & _wtoi((_bstr_t)text))
  206.             {//有子项
  207.                 pNode->get_childNodes(&pChildren);
  208.                 while (pChildren->nextNode(&pChild), pChild)
  209.                 {
  210.                     ParseDoc(raw, len, pChild);
  211.                 }
  212.             }
  213.             else
  214.             {//没有子项
  215.             }
  216.         }
  217.         return 0;
  218.     }
  219.     //d = GetBits(raw, 0, len);
  220.     //while (pChildren->nextNode(&pChild), pChild)
  221.     //{
  222.     //  pField->get_attributes(&pAttrs);
  223.     //  pAttrs->nextNode(&pNode);
  224.     //  BSTR text;
  225.     //  pNode->get_baseName(&text);//length
  226.     //  
  227.     //}
  228.     pNode->get_attributes(&pAttrs);
  229.     pAttrs->nextNode(&pAtt1);
  230.     pAtt1->get_baseName(&text);
  231.     //m_strInfo += (TCHAR *)((_bstr_t)text);
  232.     //m_strInfo += L" = ";
  233.     pAtt1->get_text(&text);
  234.     int n;
  235.     GetNumber((TCHAR *)((_bstr_t)text), &n);
  236.     //DWORD x = GetBits(m_bRawData + m_nPos, 0, n);
  237.     DWORD x = GetBits(raw, m_nPos, n);
  238.     m_vdwData.push_back(x);
  239.     //wostringstream oss;
  240.     //oss << L" = " << dec << x << endl;
  241.     //m_strInfo += oss.str();
  242.     m_nPos += n;
  243. //  m_vdwData.push_back(GetBits((TCHAR [])&m_strRawData[m_nPos], 0, n));
  244.     pAttrs->nextNode(&pAtt2);
  245.     pAtt2->get_text(&text);//name
  246.     wostringstream ostr;
  247.     ostr << (TCHAR *)((_bstr_t)text) << L" = " << m_vdwData[m_vdwData.size() -1] << endl;//name = dword
  248.     m_strInfo += ostr.str();
  249. //  wcout << "m_strInfo: " << m_strInfo.c_str() << endl;
  250.     return 0;
  251. }
  252. //递归处理xml文档,控制点决定了子节点是否显示,控制点一般会回探前向节点(<比如其>父节点)
  253. MSXML2::IXMLDOMNodePtr CXmlReader::GetFarNode(MSXML2::IXMLDOMNodePtr pNode, wstring strCode)
  254. {// ../../aaa
  255.     size_t pos = 0;
  256.     MSXML2::IXMLDOMNodePtr pParNode, pNode1 = pNode;
  257.     while (pos < strCode.size())
  258.     {
  259.         if (strCode[pos] == L'.')
  260.         {
  261.             if (strCode[++pos] != L'.'return NULL;
  262.             pNode1->get_parentNode(&pParNode);
  263.             swap(pParNode, pNode1);
  264.             pos++; pos++;//去掉'/'
  265.         }
  266.         else
  267.         {//数字
  268.             int num;
  269.             size_t len = GetNumber(const_cast<TCHAR *>(strCode.c_str()) + pos, &num);
  270.             if (num < 0)
  271.             {
  272.                 while (num < 0)
  273.                 {
  274.                     pNode1->get_previousSibling(&pParNode);
  275.                     swap(pParNode, pNode1);
  276.                     num++;
  277.                 }
  278.             }
  279.             else if (num > 0)
  280.             {
  281.                 //不要用大于0的值!
  282.             }
  283.         }
  284.     }
  285.     return pParNode;
  286. }
  287. BOOL CXmlReader::Dispose(void)
  288. {
  289.     m_nPos = 0;
  290.     m_bRawData = NULL;
  291.     m_vdwData.clear();
  292.     m_strInfo.clear();
  293.     return 0;
  294. }

xmlReader.h
  1. #pragma once
  2. typedef unsigned char BYTE;
  3. typedef unsigned short WORD;
  4. typedef unsigned long DWORD;
  5. inline BYTE MakeByte(BYTE b1, BYTE b2)
  6. {//高半字节放在b1,低半字节放在b2
  7.     BYTE b = b1 << 4;
  8.     //  b <<= 4;
  9.     b |= b2;
  10.     return b;
  11. }
  12. inline WORD MakeWord(BYTE b1, BYTE b2)
  13. {
  14.     //WORD w = b1;
  15.     //w <<= 8;
  16.     WORD w = b1 << 8;
  17.     w |= b2;
  18.     return w;
  19. }
  20. inline DWORD MakeDWord(BYTE b1, BYTE b2, BYTE b3, BYTE b4)
  21. {
  22.     DWORD d = b1 << 24;
  23.     //  d <<= 24;
  24.     d |= (b2 << 16);
  25.     d |= (b3 << 8);
  26.     d |= b4;
  27.     return d;
  28. }
  29. //DWORD GetBits(BYTE src[], size_t pos, size_t len);
  30. DWORD GetBits(BYTE *src, size_t pos, size_t len);
  31. #import "msxml6.dll" named_guids raw_interfaces_only
  32. #include <msxml.h>
  33. #include <string>
  34. #include <vector>
  35. #include <iostream>
  36. using namespace MSXML2;
  37. class CXmlReader
  38. {
  39. public:
  40.     CXmlReader(void);
  41.     CXmlReader(BYTE x[]);
  42.     ~CXmlReader(void);
  43.     int ParseData(BYTE rawData[], size_t len, MSXML2::IXMLDOMDocumentPtr pDoc);
  44.     int ParseData(BYTE rawData[], size_t len, const std::wstring& strfilename);
  45.     //递归处理xml文档,控制点决定了子节点是否显示,控制点一般会回探前向节点(<比如其>父节点)
  46.     int ParseDoc(BYTE raw[], size_t len, MSXML2::IXMLDOMNodePtr pNode);
  47.     //得到一个遥远节点的内容,主要用于控制(是否有当前节点取决于远程节点的值)
  48.     MSXML2::IXMLDOMNodePtr GetFarNode(MSXML2::IXMLDOMNodePtr pNode, std::wstring strCode);
  49. private:
  50. //public:
  51.     //类似于atoi
  52.     size_t GetNumber(TCHAR *strCode, int *num);
  53.     size_t m_nPos;
  54.     //size_t m_nDataLength;
  55.     //"11 35 20 6E 12 00 01 D8 11 48 0C 33 20 0E E9 91 1F"
  56. //  TCHAR *m_strRawData;
  57. //  std::wstring m_strRawData;
  58.     BYTE *m_bRawData;
  59. //  size_t m_nPos;
  60.     std::vector<DWORD> m_vdwData;
  61.     std::wstring m_strInfo;
  62. protected:
  63.     BOOL Dispose(void);
  64.     MSXML2::IXMLDOMDocumentPtr pDoc;
  65. };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值