天天看點

gloox代碼分析2 - xml parser子產品

gloox自己實作了xml的解析子產品,沒有用到第三方的庫(tinyXML,expat )

主要涉及的檔案:

tag.h (tag.cpp)

taghandler.h

parser.h (parser.cpp)

1. Tag一個Tag就是一個XML元素

例如:

a.

<book kind='computer'>

<store id='23'/>

<author>

    qiang

</author>

</book>

b. <book id='32'/>

c. <book>name1</book>

首先介紹一個概念: escape-string,何為escape-string?

在escape-string中:

'&'轉換成&amp;, '<'轉換成&lt;, '>'轉換成&gt;.

編碼表如下:

//

// 編碼表 (中間的空格去掉,這裡隻是為了友善顯示):

// -------------------------------------------------------

// | 字元     | 十進制 | 十六進制 | THML字元集 | Unicode |

// -------------------------------------------------------

// | " 雙引号 | & # 34; | & # x22;   | "          | /u0022 |

// -------------------------------------------------------

// | ' 單引号 | & # 39; | & # x27;   | & apos;     | /u0027 |

// -------------------------------------------------------

// | & 與     | & # 38; | & # x26;   | & amp;      | /u0026 |

// -------------------------------------------------------

// | < 小于号 | & # 60; | & # x3C;   | & lt;       | /u003c |

// -------------------------------------------------------

// | > 大于好 | & # 62; | & # x3E;   | & gt;       | /u003e |

// -------------------------------------------------------

gloox - APIs

Tag::escape()    功能: string -> escape-string

Tag::relax() 功能: escape-string -> string

主要成員變量:

attributes - 所有屬性的list

name - 節點名字

cdata - 節點資料,例如<name>cdata</name>中的cdata

children - 所有的子節點

parent - 父節點指針,如果沒有則為空

bool incoming - 表示構造xml node的時候傳入的字元串是否是escape-string,如果是,需要在構造的時候調用relex把escape-string轉換成string.

主要方法:

也就是一些針對name/children/attributes/cdata進行增加/删除/修改的方法

xml()方法傳回該節點的一個完整的xml資料流

findTag和findTagList提供對XPath的支援.

例如:

螢幕将輸出:

<book kind='computer'><store id='23'/><author>qiang</author></book>

1

gloox代碼分析2 - xml parser子產品

#include <iostream>

2

gloox代碼分析2 - xml parser子產品

#include "tag.h"

3

gloox代碼分析2 - xml parser子產品

4

gloox代碼分析2 - xml parser子產品

#pragma comment( lib, "gloox.lib" )

5

gloox代碼分析2 - xml parser子產品

using namespace gloox;

6

gloox代碼分析2 - xml parser子產品

7

gloox代碼分析2 - xml parser子產品

// <book kind='computer'>

8

gloox代碼分析2 - xml parser子產品

//     <store id='23'/>

9

gloox代碼分析2 - xml parser子產品

//     <author>

10

gloox代碼分析2 - xml parser子產品

//       qiang

11

gloox代碼分析2 - xml parser子產品

//     </author>

12

gloox代碼分析2 - xml parser子產品

// </book>

13

gloox代碼分析2 - xml parser子產品

//

14

gloox代碼分析2 - xml parser子產品

15

gloox代碼分析2 - xml parser子產品

16

gloox代碼分析2 - xml parser子產品
gloox代碼分析2 - xml parser子產品

int main( int argc, char* argv[] ) {

17

gloox代碼分析2 - xml parser子產品

   Tag* tag_book = new Tag( "book" );

18

gloox代碼分析2 - xml parser子產品

   tag_book->addAttribute( "kind", "computer" );

19

gloox代碼分析2 - xml parser子產品

20

gloox代碼分析2 - xml parser子產品

   Tag* tag_store = new Tag( "store" );

21

gloox代碼分析2 - xml parser子產品

   tag_store->addAttribute( "id", "32" );

22

gloox代碼分析2 - xml parser子產品

23

gloox代碼分析2 - xml parser子產品

   Tag* tag_author = new Tag( "author", "qiang" );

24

gloox代碼分析2 - xml parser子產品

25

gloox代碼分析2 - xml parser子產品

   tag_book-> addChild( tag_store );

26

gloox代碼分析2 - xml parser子產品

   tag_book-> addChild( tag_author );

27

gloox代碼分析2 - xml parser子產品

28

gloox代碼分析2 - xml parser子產品

   std::cout<<tag_book->xml()<< std::endl;

29

gloox代碼分析2 - xml parser子產品

  return 0 ;

30

gloox代碼分析2 - xml parser子產品

}

gloox代碼分析2 - xml parser子產品

2. TagHandler是一個接收parser解析完成的tag的接口,繼承該類,則可以接收parser解析的tag對象事件.

隻有一個接口

virtual void handleTag( Tag *tag ) = 0 - 接收解析完的tag

3. Parser一個XML解析器

提供的接口非常簡潔,隻需要一個TagHandler來構造,該handler接收并處了解析的tag,另外隻有一個feed接口來填充資料.

要注意的是feed接口填充的資料必須是一個格式正确的xml,否則無法解析,也就是說parser不會判斷xml的格式。

例如:

下 面的例子中對feed來說分開填充和一次性填充資料的效果是一樣的,也就是scenario1和scenario2的效果是一樣的,這也剛好和上層應用中 TCP 流處理的方式統一,對于接收到伺服器端的XML流,無論是否完整,隻需要直接feed就可以了。handlerTag方法将收到兩個

xml tag解析完成的事件,分别來自scenario1和scenario2,螢幕将輸出:

<book kind='computer'><store id='23'/><author>qiang</author></book>

<book kind='computer'><store id='23'/><author>qiang</author></book>

1

gloox代碼分析2 - xml parser子產品

#include <iostream>

2

gloox代碼分析2 - xml parser子產品

#include "tag.h"

3

gloox代碼分析2 - xml parser子產品

#include "parser.h"

4

gloox代碼分析2 - xml parser子產品

5

gloox代碼分析2 - xml parser子產品

#pragma comment( lib, "gloox.lib" )

6

gloox代碼分析2 - xml parser子產品

using namespace gloox;

7

gloox代碼分析2 - xml parser子產品

8

gloox代碼分析2 - xml parser子產品

// <book kind='computer'>

9

gloox代碼分析2 - xml parser子產品

//    <store id='23'/>

10

gloox代碼分析2 - xml parser子產品

//    <author>

11

gloox代碼分析2 - xml parser子產品

//      qiang

12

gloox代碼分析2 - xml parser子產品

//    </author>

13

gloox代碼分析2 - xml parser子產品

// </book>

14

gloox代碼分析2 - xml parser子產品

//

15

gloox代碼分析2 - xml parser子產品

//

16

gloox代碼分析2 - xml parser子產品

17

gloox代碼分析2 - xml parser子產品
gloox代碼分析2 - xml parser子產品

class TagHandlerImpl : public TagHandler {

18

gloox代碼分析2 - xml parser子產品

public:

19

gloox代碼分析2 - xml parser子產品
gloox代碼分析2 - xml parser子產品

    ~TagHandlerImpl()

gloox代碼分析2 - xml parser子產品

{}

20

gloox代碼分析2 - xml parser子產品

21

gloox代碼分析2 - xml parser子產品
gloox代碼分析2 - xml parser子產品

    void run()

gloox代碼分析2 - xml parser子產品

{

22

gloox代碼分析2 - xml parser子產品

       Parser* parser = new Parser(this);

23

gloox代碼分析2 - xml parser子產品

      // scenario1

24

gloox代碼分析2 - xml parser子產品

       std::string data = "<book kind='computer'><store id='23'/><author>qiang</author></book>";

25

gloox代碼分析2 - xml parser子產品

       parser->feed( data );

26

gloox代碼分析2 - xml parser子產品

27

gloox代碼分析2 - xml parser子產品

      // scenario2

28

gloox代碼分析2 - xml parser子產品

       std::string data1 = "<book kind='computer";

29

gloox代碼分析2 - xml parser子產品

       std::string data2 = "'><store id='23'/><auth";

30

gloox代碼分析2 - xml parser子產品

       std::string data3 = "or>qiang</author></book>";

31

gloox代碼分析2 - xml parser子產品

       parser->feed( data1 );

32

gloox代碼分析2 - xml parser子產品

       parser->feed( data2 );

33

gloox代碼分析2 - xml parser子產品

       parser->feed( data3 );

34

gloox代碼分析2 - xml parser子產品

     }

35

gloox代碼分析2 - xml parser子產品

36

gloox代碼分析2 - xml parser子產品
gloox代碼分析2 - xml parser子產品

    void handleTag( Tag *tag )

gloox代碼分析2 - xml parser子產品

{

37

gloox代碼分析2 - xml parser子產品

       std::cout<<tag->xml()<<std::endl;

38

gloox代碼分析2 - xml parser子產品

     }

39

gloox代碼分析2 - xml parser子產品

};

40

gloox代碼分析2 - xml parser子產品

41

gloox代碼分析2 - xml parser子產品
gloox代碼分析2 - xml parser子產品

int main( int argc, char* argv[] ) {

42

gloox代碼分析2 - xml parser子產品

   TagHandlerImpl* taghandlerImpl = new TagHandlerImpl();

43

gloox代碼分析2 - xml parser子產品

   taghandlerImpl->run();

44

gloox代碼分析2 - xml parser子產品

45

gloox代碼分析2 - xml parser子產品

  return 0;

46

gloox代碼分析2 - xml parser子產品

}