寫了一個mircro XML解析器,附原始碼
不喜歡看人廢話喜歡直奔主題的是同學可以直接: goto 附件下載。
mirco 的意思是比 tiny 還要 tiny。
GUI 模板用 XML 做是最合適的。方便嵌入指令碼,方便編輯修改,方便嵌入面板描述,用 XML 做模板,寫起 GUI 編輯器也要方便得多。
以前幾個的 GUI 模板解析器用的是 MSXML 來實現的,不過它提供的介面字串型別全是 BSTR,自己的介面又是 TCHAR*,每一次的呼叫都會有一次字串轉換,效率很低。而且一想到程式碼裡有 QueryInteface,AddRef,Release ,心裡就不踏實,擔心吊膽的。
於是又打算用 TinyXML,看了幾遍程式碼,發現它對寬字符集的支援有些古怪。程式碼裡其它的雜七雜八的東西有點多,程式碼風格什麼的也不大喜歡。
於是自己寫了一個簡單的,雖然有錯誤檢測機制,不過沒有提供查詢介面,因為這樣我覺得使介面不整潔。其實要知道 XML 哪裡出錯了很簡單,隨便拿個瀏覽器開啟就行了,提示得非常詳細。不過以後可能會根據需要新增上。XPATH 支援也是如此。介面函式全部使用 UNICODE。
測試程式碼:
1: // cexer
2: #include "./include/XML/xmlfile.h"
3: #include "./include/XML/xmlelement.h"
4: #include "./include/XML/xmldeclaration.h"
5:#include "./include/XML/xmlunknown.h"
6: #include "./include/XML/xmlcomment.h"
7: #include "./include/XML/xmltext.h"
8: #include "./include/XML/xmlattribute.h"
9:
10: using namespace cexer;
11: using namespace cexer::xml;
12:
13:
14: // c++ std
15: #include<iostream>
16: using namespace std;
17:
18:
19: int wmain( int argc,WCHAR** argv )
20: {
21: wcout.imbue( std::locale("chs") );
22:
23: XmlFile document( L"./XMLs/utf16le_ns.xml" );
24: if ( !document.load() )
25: {
26: wcout<<L"解析失敗"<<endl;
27: return 0;
28: }
29:
30: XmlElement* root = document.element();
31: if ( !root )
32: {
33: wcout<<L"沒有找到根結點"<<endl;
34: return 0;
35: }
36:
37: wcout<<root->name()<<endl;
38:
39:
40: XmlNode* firstChild = root->firstChild();
41: if ( !firstChild )
42: {
43: wcout<<L"沒有子結點"<<endl;
44: return 0;
45: }
46:
47: XmlDeclaration* declar = xml_cast<XmlDeclaration*>( firstChild );
48: if ( !declar )
49: {
50: wcout<<L"第一個子結點不是宣告"<<endl;
51: }
52: else
53: {
54: wcout<<L"第一個節點是宣告"<<endl;
55: wcout<<L"version = "<<declar->version()<<endl;
56: wcout<<L"encoding = "<<declar->encoding()<<endl;
57: wcout<<L"standalone = "<<declar->standalone()<<endl;
58: }
59:
60: XmlComment* comment = xml_cast<XmlComment*>( firstChild->next() );
61: if ( !comment )
62: {
63: wcout<<L"第二個子結點不是註釋"<<endl;
64: }
65: else
66: {
67: wcout<<L"第二個結點是註釋:"<<comment->value()<<endl;
68: }
69:
70: XmlElement* window = root->element( L"window" );
71: if ( !window )
72: {
73: wcout<<L"沒有找到window元素結點"<<endl;
74: return 0;
75: }
76: wcout<<window->attributeValue( L"text" )<<endl;
77:
78:
79: XmlElement* nextWindow = window->nextElement( L"window" );
80: if ( !nextWindow )
81: {
82: wcout<<L"沒有找到後面的window元素結點"<<endl;
83: }
84: else
85: {
86: wcout<<L"後面還有一個window元素結點 ";
87: wcout<<nextWindow->attributeValue(_T("name"))<<endl;
88: }
89:
90: XmlElement* panel = window->element( L"panel" );
91: if ( panel )
92: {
93: wcout<<panel->attributeValue( L"caption" )<<endl;
94: }
95:
96: window->setAttribute( L"styleAdd",L"WS_VISIBLE" );
97: window->setAttribute( L"styleRemove",L"\";<>=&\"" );
98:
99: if ( !document.save( L"./XMLs/modified/utf16le_ns.xml" ) )
100: {
101: wcout<<L"儲存失敗"<<endl;
102: }
103:
104: return 0;
105: }
編碼支援:
因為內部使用 MultiBytesToWideChar 和 WideCharToMultiBytes 來實現字符集/編碼的操作,因此對字符集/編碼的支援很靈活,能夠支援以上兩個函式支援的所有編碼,只需簡單的修改即可新增新的支援。預置了幾種編碼支援:
- UTF-16LE(UNICODE)
- GBK
- BIG5
- GB2312
- UTF-7
- UTF-8
對於沒有編碼宣告並且沒有檔案頭簽名檔案,都視為 UTF-8 編碼。以上的程式碼當中的 XML 檔案就是一個沒有簽名,沒有宣告的 UTF-16LE 編碼的 XML 檔案。
TinyXML 內部解析字串全是以 char* 型別來解析,只支援多位元組編碼如 UTF-8,ASCII,不支援 UNICODE 編碼。如對中文的支援就比較古怪,如果 XML 以 UTF-8 格式儲存,則設定“值”的時候必須自己把字串轉換為 UTF-8 再設定,而在取得值以後,則必須自己將它們從 UTF-8 轉換成 UNICODE 或 ASCII,否則就是亂碼。
主要是 TinyXML 為了跨平臺,所以沒有像 MultiBytesToWideChar 和 WideCharToMultiBytes 這種函式的直接支援。不過如果是為了跨平臺,這兩個函式也可以考慮自己實現。
節點型別轉換:
因為在記憶體當中,元素,註釋,文字,宣告等結點都是儲存為一個基類的指標,因此在使用的時候必須要有一個型別轉換的動作。也有一些 XML 解析器比較簡單,其中只有文件,元素,屬性這三種結點,記憶體當中存的全部都是元素集合,元素當中再存有屬性集合,用不著型別轉換,不過這種 XML 將 XML 讀入記憶體再存入磁碟檔案當中時,會丟失掉 XML 檔案原有的格式。
TinyXML 在記憶體當中所有的結點(除屬性)都以基類 TiXmlNode 指標的形式存放 ,從一個 TiXmlNode* 進行型別轉的方法是這樣的:
首先在基 TiXmlBase 宣告一組虛擬函式
1: class TiXmlNode
2: {
3: virtual TiXmlDocument* ToDocument() { return 0; }
4: virtual TiXmlElement* ToElement() { return 0; }
5: virtual TiXmlComment* ToComment() { return 0; }
6: virtual TiXmlUnknown* ToUnknown() { return 0; }
7: virtual TiXmlText* ToText() { return 0; }
8: virtual TiXmlDeclaration* ToDeclaration() { return 0; }
9: };
然後在子類當中各自重寫向自己型別轉換的那一個虛擬函式。如在 XmlElement 和 XmlComment 當中:
1: class XmlElement
2: {
3: virtual TiXmlElement* ToElement() { return this; }
4: };
5:
6: class XmlComment
7: {
8: virtual TiXmlComment* ToComment() { return this; }
9: };
這樣做很方便,不過如果要寫一個新的 XML 結點型別,就比較麻煩了,必須重新修改基類 TiXmlNode 的程式碼,整個 XML 解析器的程式碼都得重新編譯一遍。
我則借用了 COM 的 Queryinterface 的方式。在基類 XmlCastable 當中聲明瞭一個虛擬函式 query,任意結點呼叫這個函式,輸入一個型別,若該結點是這個型別,那麼就輸出指標的值並返回 true,否則輸出 NULL 並返回 false。
相關推薦
寫了一個mircro XML解析器,附原始碼
不喜歡看人廢話喜歡直奔主題的是同學可以直接: goto 附件下載。 mirco 的意思是比 tiny 還要 tiny。 GUI 模板用 XML 做是最合適的。方便嵌入指令碼,方便編輯修改,方便嵌入面板描述,用 XML 做模板,寫起 GUI 編輯器也要方便得多。 以前幾個的 GUI 模板解
自己寫了一個帶placeHolder的textView,分享給大家
#import <UIKit/UIKit.h> @interface PlaceHolderTextView : UITextView { UILabel *placeHolder;//編輯區 } @property(retain, nonatomic)
第三章 XML解析器,驗證器,轉換器,編輯器等
xml有這麼多的規則,寫出來的xml文字檔案到底符不符合要求呢? 用人工檢驗的方式效率太低,也容易出錯,所以開發出了程式來驗證。 xml驗證器: XML DTD和XML Schema,後者用來替代前者。 如果 XML 文件存在錯誤,那麼程式就不應當繼
Android Studio中寫了一個工具類,進行測試時在Manifest.xml中寫
這是包,utils下的HttpUtils是工具類 在Manifest.xml檔案下寫<instrumentation時報錯,<instrumentation></instrumentation>部分程式碼如下:<instrumentati
最近開始努力學python 寫了一個python小代碼:判斷一個登陸程序,如果賬號密碼輸錯3次,鎖定賬號無法再登陸
登陸 readlines 輸入 連續 nbsp 努力 一個 取數據 lis 1 count = 0 2 username = ‘zhangsan‘ 3 userpassword = ‘111111‘ 4 5 f = open(‘lock.txt‘,‘r+‘
原生JS寫了一個小demo,根據輸入的數字生成不同背景顏色的小方塊兒~
top == UNC 定位元素 demo TE tostring eight 地方 昨天練習寫了這個小demo,個人覺得通過設置定位元素left和top的值,來實現換行的功能,這種方法很巧妙~ 另外,如下代碼中的隨機顏色的獲取,還請各位前輩多多指教:需要改進的地方;或者有
CCF-棋局評估 201803-04(版本 2.0)------(之前寫了一個臃腫的1.0版 ,還沾沾自喜 233)
核心 color namespace ace for play class 一個 while 核心 : 博弈搜索樹 雙方得分互為相反數 dfs (x,y,player): 玩家player下完(x,y)之後的得分最大值 易錯: 先判斷輸贏,再判斷
給女朋友用Python寫了一個自動抽獎程序!Python在手,獎品我有!
com () 單身 代碼 女孩子 nbsp 不能 是不是 apt 我相信大部分的女孩子都是喜歡買買買的,我還沒有見過不喜歡買東西的女孩子,當然很多東西也是有抽獎這項優惠的,很多小程序都有抽獎這個功能的,好了廢話不多說了,為了給女朋友寫這款抽獎程序,可謂是嘔心瀝血!不過看到她
最新用WPF為觸摸屏寫了一個手寫程序,雙格輸入的
nload size alt wpf 一個 ast 點擊 fill fonts 原文:最新用WPF為觸摸屏寫了一個手寫程序,雙格輸入的 雙格輸入可以提高手寫速度,當前字寫完以後
寫了一個預約東南大學體育場館的python指令碼,目前剛剛實現功能,後續會繼續完善
看到git上有人寫了一個自動預約的指令碼,正好前段時間在學python爬蟲和指令碼,索性也寫了一個,大佬直接略過。 目前沒有做圖形化,賬號和預約資訊也是手動輸入的,我也只寫了羽毛球和乒乓球,其實就是一個屬性的值。嫌麻煩的同學可以寫一個文字檔案,儲存這些資訊,然後倒入到腳本里,每次稍作修改就可以了。如果基友固
Python 運用所學知識製作一個歌詞解析器,要求:輸入時間給出對應歌詞
學了將近兩週python了,遇到了一道挺有意思的題分享一下: 製作一個歌詞解析器,要求:輸入一個時間點能給出對應時間的歌詞 廢話不多說,直接上圖,基本每步都有註釋: mulrc = '''[ti:藍蓮花] [ar:許巍] [al:留聲十年絕版青
繼續sprintf函式,這次親自動手寫了一個myprintf,是不是更有意思了,當然別指望我的程式碼沒有bug。
#include <stdio.h> typedef char *va_list; #define __va_rounded_size(TYPE) \ (((sizeof(TYPE)+sizeof(int)-1)/sizeof(int))*sizeof(int
面對散落各處的收藏和筆記,我寫了一個 App 用人工智慧來管理
你是否收藏了很多文章,回頭想用的時候卻不知道自己放在了哪個平臺,然後各個app都搜尋一遍?或者存了很多文章在pocket,卻從來沒有再看過?今天要給大家推薦一個知識的『聯結器』——優讀。 這是一款集收藏自動打標籤,待讀過期自動刪除,文章劃線筆記,圖書拍照識別筆記於一體的知識集中管理工具,更
剛學了兩天python爬蟲,就寫了一個分享給大家!爬蟲真的很簡單!
經過兩天的摸索,終於寫出了一個小小小爬蟲。這其中的波折是這樣的,聽我娓娓道來。我的電腦是沒有配置python環境的,所以首先要上官網下載python的環境檔案。 當然在學習Python的道路上肯定會困難,沒有好的學習資料,怎麼去學習呢? 學習Python中有不明白推薦加入交流群
並歸排序(看別人的看不懂,自己寫了一個),排序思想是一樣的
public int[] intArray = {8,5,10,55,88,22,14,36,82,54,10,74,22}; @RequestMapping(value="hello") public int[] getHello(int[] intArray1) {
閒來無事,用Python寫了一個pm2.5查詢小程式,還是很有趣的
今天教大家用python完成首個MVP,如何用CLI(command-line interface,命令列介面)來執行第一個空氣質量查詢程式。 更多Python視訊、原始碼、資料加群960410445免費獲取 知識點
厲害了!如何Python寫一個安卓APP,附原始碼!
熱文導讀 | 點選標題閱讀 作者: “又耳的筆記本” 文末附原始碼地址 來源:http://youerning.blog.51cto.com/10513771/1733534 本文會帶大家寫一個Hello world並瞧一瞧Python版實現的android 2048的程式碼 前言
maven工程中,controller下寫了一個url請求,冒404
昨天在controll層寫了一請求,但是訪問該url,冒404,特別古怪的一個問題。大哥給了我一個反編譯class軟體(檢視eclipse的編譯結果) 去eclipse編譯資料夾下找到該class檔案,發現並沒有寫入進去。 首先我做了clean下編譯軟體,但是效果是並沒有
自己寫了一個c++ bitset,功能非常齊全!
c++ bitset用途很廣,而理解它的最好方式莫過於自己寫一個,重新造輪子還是非常有樂趣的,廢話不多說了,貼程式碼。 首先是一些必要的函式,封裝在名字空間mystd裡面。/*如果發現有bug,望高手批評指正!相互交流交流! * 轉載本文的註明一下出處,謝謝! */ #
練習python寫了一個四則運算程式,支援乘方和“.3"這種格式
#!/usr/bin/python #coding=utf-8 # 本程式由使用者輸入一個表示式字串,然後計算這個表示式的值 # 表示式是一個四則運算表示式,可以包含^操作符# 注意:乘方用^運算子,支援".3"這種表示小數的形式。負數需要用括號擴起來 # 思路:利用棧的方