首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

輕量級跨平台 C++ XML 解析類:CPacket 設計與使用

     編輯:關於VC++

動機與設計原則

.NET 平台操作 XML 極為便利,但 C++ 標準庫缺乏原生支援。IBM XML4C (Xerces-C) 功能強大卻體積龐大(數 MB),且對 GB2312 編碼支援棘手。作者依據「功能最精簡、最實用、最常用」原則,自行實作一套僅含三個核心類別的輕量級解析器,專注於**解析、查找、DOM 樹建立**,不支援 XML 生成(建議直接字串拼接)。

核心類別架構

核心 API 快速參考

1. 建立 DOM 樹

// 從字串解析
CPacket::BuiltTree(const char* pBuf, int nBufSize);
// 從檔案解析
CPacket::BuiltTree(LPCTSTR pXmlPath);

範例

CPacket inPacket;
DOMElement* node = nullptr;
inPacket.BuiltTree(strXml.c_str(), strXml.size()); // 字串
inPacket.BuiltTree(_T("c:\\1.xml"));               // 檔案

2. 動態建立/插入節點

// 絕對路徑(從根節點):若中間節點不存在會自動建立
CPacket::CreateElement(_T("/Root/Cust/Tel"));

// 相對路徑(從當前節點):需先 SetCurrentElement
CPacket::CreateElement(_T("Root/Cust/Tel"));

3. 節點查找(四種模式)

// 一般查找,支援絕對/相對路徑
DOMElement* SearchElement(char* szNodeName);

// 指定屬性查找:如尋找 Id="1" 的 TelNum
DOMElement* SearchElement(char* szNodeName, char* szProp, char* szId);

// 遍歷同級節點(最快):參數決定是否移動當前指標
DOMElement* SearchNextElement(bool bMoveNext = TRUE);

// 結合名稱與屬性遍歷下一個匹配節點
DOMElement* SearchNextElement(char* szNodeName, char* szProp = NULL, char* szId = NULL);

完整使用範例

void main()
{
    string strXml = "<Xml><Body><TelNums><TelNum Id='1'>123</TelNum><TelNum Id='2'>456</TelNum></TelNums></Body></Xml>";
    CPacket inPacket;
    DOMElement* pNode = nullptr;

    inPacket.BuiltTree(strXml.c_str(), strXml.size());
    printf("%s", inPacket.GetXml(NULL).c_str()); // 輸出完整 XML

    // 1. 絕對路徑定位父節點
    pNode = inPacket.SearchElement("/Xml/Body/TelNums/TelNum");
    if (!pNode) return;
    inPacket.SetCurrentElement(pNode);

    // 2. 遍歷所有 TelNum 同級節點
    while (pNode) {
        printf("%s\n", pNode->getTextContent());
        pNode = inPacket.SearchNextElement(true);
    }

    // 3. 重置至根節點,帶屬性查找
    inPacket.ResetCurrentNode();
    pNode = inPacket.SearchElement("TelNum", "Id", "1");
    if (pNode) printf("Found: %s\n", pNode->getTextContent());

    // 4. 建立新 XML 文件
    CPacket outPacket;
    outPacket.SetRootTag("Root");
    DOMElement* pNew = outPacket.CreateElement("/Root/Cust/Tel");
    pNew->setTextContent("075507895461");
    printf("%s", outPacket.GetXml(NULL).c_str());
}

已知限制與注意事項

  • 編碼支援以 ASCII/UTF-8 為主,中文編碼需自行測試。
  • 無 DTD/Schema 驗證、無 XPath、無命名空間完整支援。
  • 程式碼為早期作品,測試覆蓋率有限,生產環境建議改用成熟庫(TinyXML2, pugixml, RapidXML)。
  • 作者聯絡:mycrolee@163.com(原信箱 mycro@163.com 已失竊)。

結語

此解析器適合嵌入式、舊專案維護或教學理解 DOM 樹結構。現代 C++ 專案強烈建議採用標準化、高效能的開源替代方案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
類別職責關鍵成員
DOMElement節點類別tag、level、parent、childlist
DOMDocument文件模型,管理 DOM 樹解析邏輯、樹建立
CPacket對外門面,封裝操作介面建樹、查找、建立節點、序列化輸出