天天看點

TinyXmlParser開源喽~~~

優點:

高效、簡單、易用的xml解析器。

學習時間,分分鐘。

支援中文标簽名與屬性名,支援下劃線,減号等分隔符。

解析速度超過,查找速度超快,支援格式化。

缺點:不支援xml schema,dtd校驗。

maven引用坐标:

<a href="http://my.oschina.net/tinyframework/blog/194574#">?</a>

1

2

3

4

5

<code>&lt;</code><code>dependency</code><code>&gt;</code>

<code>&lt;</code><code>groupid</code><code>&gt;org.tinygroup&lt;/</code><code>groupid</code><code>&gt;</code>

<code>&lt;</code><code>artifactid</code><code>&gt;xmlparser&lt;/</code><code>artifactid</code><code>&gt;</code>

<code>&lt;</code><code>version</code><code>&gt;0.0.12&lt;/</code><code>version</code><code>&gt;</code>

<code>&lt;/</code><code>dependency</code><code>&gt;</code>

解析下面xml

6

7

8

9

10

11

12

13

14

15

16

17

18

<code>&lt;?</code><code>xml</code> <code>version</code><code>=</code><code>"1.0"</code><code>?&gt;</code>

<code>&lt;</code><code>students</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>student</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>name</code><code>&gt;john&lt;/</code><code>name</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>grade</code><code>&gt;b&lt;/</code><code>grade</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>age</code><code>&gt;12&lt;/</code><code>age</code><code>&gt;</code>

<code>    </code><code>&lt;/</code><code>student</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>name</code><code>&gt;mary&lt;/</code><code>name</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>grade</code><code>&gt;a&lt;/</code><code>grade</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>age</code><code>&gt;11&lt;/</code><code>age</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>name</code><code>&gt;simon&lt;/</code><code>name</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>age</code><code>&gt;18&lt;/</code><code>age</code><code>&gt;</code>

<code>&lt;/</code><code>students</code><code>&gt;</code>

示例代碼:

19

20

21

22

<code>public</code> <code>class</code> <code>testxmlparser {</code>

<code>    </code><code>public</code> <code>static</code> <code>void</code> <code>main(string[] args)</code><code>throws</code> <code>throwable {</code>

<code>        </code><code>file file =</code><code>new</code> <code>file(</code><code>"e:/test/students.xml "</code><code>);</code>

<code>        </code><code>xmlstringparser parser =</code><code>new</code> <code>xmlstringparser();</code>

<code>        </code><code>xmldocument document = parser.parse(ioutils.readfrominputstream(</code>

<code>                </code><code>new</code> <code>fileinputstream(file),</code><code>"utf-8"</code><code>));</code>

<code>        </code><code>printstudents(document.getroot());</code>

<code>    </code><code>}</code>

<code>    </code><code>private</code> <code>static</code> <code>void</code> <code>printstudents(xmlnode studentsnode) {</code>

<code>        </code><code>for</code><code>(xmlnode studentnode:studentsnode.getsubnodes(</code><code>"student"</code><code>)){</code>

<code>            </code><code>printstuent(studentnode);</code>

<code>        </code><code>}</code>

<code>    </code><code>private</code> <code>static</code> <code>void</code> <code>printstuent(xmlnode studentnode) {</code>

<code>        </code><code>printsubtagbyname(studentnode,</code><code>"name"</code><code>);</code>

<code>        </code><code>printsubtagbyname(studentnode,</code><code>"grade"</code><code>);</code>

<code>        </code><code>printsubtagbyname(studentnode,</code><code>"age"</code><code>);</code>

<code>    </code><code>private</code> <code>static</code> <code>void</code> <code>printsubtagbyname(xmlnode studentnode,string tagname) {</code>

<code>        </code><code>system.out.println( studentnode.getsubnode(tagname).getcontent());</code>

<code>}</code>

格式化示例:

<code>xmldocument doc;</code>

<code>doc =</code><code>new</code> <code>xmlstringparser()</code>

<code>       </code><code>.parse(</code><code>"&lt;html 中='文'&gt;&lt;head&gt;&lt;title&gt;aaa&lt;/title&gt;&lt;/head&gt;&lt;/html&gt;"</code><code>);</code>

<code>xmlformater f =</code><code>new</code> <code>xmlformater();</code>

<code>system.out.println(f.format(doc)); </code>

運作結果:

<code>&lt;</code><code>html</code> <code>中="文"&gt;</code>

<code>  </code><code>&lt;</code><code>head</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>title</code><code>&gt;</code>

<code>      </code><code>aaa     </code>

<code>    </code><code>&lt;/</code><code>title</code><code>&gt;</code>

<code>  </code><code>&lt;/</code><code>head</code><code>&gt;</code>

<code>&lt;/</code><code>html</code><code>&gt;</code>

性能測試:

建構下面的節點規模:

<code>htmlnode node =</code><code>null</code><code>;</code>

<code>    </code><code>public</code> <code>namefiltertest() {</code>

<code>        </code><code>node =</code><code>new</code> <code>htmlnode(</code><code>"root"</code><code>);</code>

<code>        </code><code>for</code> <code>(</code><code>int</code> <code>i =</code><code>0</code><code>; i &lt;</code><code>60</code><code>; i++) {</code>

<code>            </code><code>htmlnode a = node.addnode(</code><code>new</code> <code>htmlnode(</code><code>"a"</code> <code>+ i));</code>

<code>            </code><code>for</code> <code>(</code><code>int</code> <code>j =</code><code>0</code><code>; j &lt;</code><code>60</code><code>; j++) {</code>

<code>                </code><code>htmlnode b = a.addnode(</code><code>new</code> <code>htmlnode(</code><code>"b"</code> <code>+ j));</code>

<code>                </code><code>for</code> <code>(</code><code>int</code> <code>k =</code><code>0</code><code>; k &lt;</code><code>60</code><code>; k++) {</code>

<code>                    </code><code>b.addnode(</code><code>new</code> <code>htmlnode(</code><code>"c"</code> <code>+ k));</code>

<code>                </code><code>}</code>

<code>            </code><code>}</code>

也就是節點數60+60*60+60*60*60個節點數時,進行下面的查找:

<code>long</code> <code>t21 = system.currenttimemillis();</code>

<code>fastnamefilter fast =</code><code>new</code> <code>fastnamefilter(node);</code>

<code>long</code> <code>t22 = system.currenttimemillis();</code>

<code>system.out.println(</code><code>"fast初始化用時"</code> <code>+ (t22 - t21));</code>

<code>long</code> <code>t1 = system.currenttimemillis();</code>

<code>string nodename =</code><code>null</code><code>;</code>

<code>for</code> <code>(</code><code>int</code> <code>x =</code><code>0</code><code>; x &lt;</code><code>10000</code><code>; x++) {</code>

<code>    </code><code>nodename = fast.findnode(</code><code>"b6"</code><code>).getnodename();</code>

<code>long</code> <code>t2 = system.currenttimemillis();</code>

<code>system.out.println(</code><code>"fastnamefilter用時"</code> <code>+ (t2 - t1));</code>

<code>fast初始化用時</code><code>130</code>

<code>fastnamefilter用時</code><code>39</code>

也就是說在219661個節點規模下,查找指定節點10000次,隻用時39ms,還有比這個更快的麼?

如果到此為止,其實也沒有啥,它提供的過濾功能可以滿足絕大多數的應用場景,先看看接口:

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

<code>public</code> <code>interface</code> <code>nodefilter&lt;t</code><code>extends</code> <code>node&lt;t&gt;&gt; {</code>

<code>    </code><code>/**</code>

<code>     </code><code>* 初始化節點</code>

<code>     </code><code>*</code>

<code>     </code><code>* @param node</code>

<code>     </code><code>*/</code>

<code>    </code><code>void</code> <code>init(t node);</code>

<code>     </code><code>* 設定必須包含的屬性及對應屬性的值,必須存在</code>

<code>     </code><code>* @param includeattributes</code>

<code>    </code><code>void</code> <code>setincludeattribute(map&lt;string, string&gt; includeattributes);</code>

<code>     </code><code>* 設定必須包含的屬性及對應的屬性的值,必須存在</code>

<code>     </code><code>* @param key</code>

<code>     </code><code>* @param value</code>

<code>    </code><code>void</code> <code>setincludeattribute(string key, string value);</code>

<code>     </code><code>* 設定必須包含的屬性</code>

<code>     </code><code>* @param includeattribute</code>

<code>    </code><code>void</code> <code>setincludeattributes(string... includeattribute);</code>

<code>     </code><code>* 設定必須排除的屬性及對應屬性值 如果包含屬性,但屬性的值與map中不相同,允許存在該屬性 若包含屬性且屬性的值與map中相同,則不允許存在該屬性</code>

<code>     </code><code>* @param excludeattribute</code>

<code>    </code><code>void</code> <code>setexcludeattribute(map&lt;string, string&gt; excludeattribute);</code>

<code>     </code><code>* 設定必須排除的屬性,指定的屬性不能存在</code>

<code>    </code><code>void</code> <code>setexcludeattribute(string... excludeattribute);</code>

<code>     </code><code>* 設定必須包含的内容,隻需要context中包include該值就行</code>

<code>     </code><code>* @param includetext</code>

<code>    </code><code>void</code> <code>setincludetext(string... includetext);</code>

<code>     </code><code>* 設定必須排除的内容</code>

<code>     </code><code>* @param excludetext</code>

<code>    </code><code>void</code> <code>setexcludetext(string... excludetext);</code>

<code>     </code><code>* 設定必須包含的子節點</code>

<code>     </code><code>* @param includenode</code>

<code>    </code><code>void</code> <code>setincludenode(string... includenode);</code>

<code>     </code><code>* 設定父節點不允許的節點名稱</code>

<code>     </code><code>* @param excludebynode</code>

<code>    </code><code>void</code> <code>setexcludebynode(string... excludebynode);</code>

<code>     </code><code>* 設定父節點必須包含的節點名稱</code>

<code>     </code><code>* @param includebynode</code>

<code>    </code><code>void</code> <code>setincludebynode(string... includebynode);</code>

<code>     </code><code>* 設定必須排除的子節點</code>

<code>     </code><code>* @param excludenode</code>

<code>    </code><code>void</code> <code>setexcludenode(string... excludenode);</code>

<code>     </code><code>* 設定至少包含一個指定名稱的節點</code>

<code>     </code><code>* @param xorsubnode</code>

<code>    </code><code>void</code> <code>setxorsubnode(string... xorsubnode);</code>

<code>     </code><code>* 設定至少包含一個指定名稱屬性</code>

<code>     </code><code>* @param xorproperties</code>

<code>    </code><code>void</code> <code>setxorproperties(string... xorproperties);</code>

<code>     </code><code>* 清除過濾條件</code>

<code>    </code><code>void</code> <code>clearcondition();</code>

<code>     </code><code>* 設定要搜尋的節點名稱</code>

<code>    </code><code>void</code> <code>setnodename(string nodename);</code>

<code>     </code><code>* 查找指定節點名稱及滿足其他條件的節點清單</code>

<code>     </code><code>* @param nodename</code>

<code>     </code><code>* @return</code>

<code>    </code><code>list&lt;t&gt; findnodelist(string nodename);</code>

<code>     </code><code>* 根據名字及其他條件查找節點,如果有多個,也隻傳回第一個</code>

<code>     </code><code>*            要查找的節點名稱</code>

<code>    </code><code>t findnode(string nodename);</code>

<code>     </code><code>* 搜尋符合設定的節點名稱的節點,如果有多個,則隻傳回找到的第一個</code>

<code>    </code><code>t findnode();</code>

<code>     </code><code>* 搜尋符合設定的節點名稱的節點清單</code>

<code>    </code><code>list&lt;t&gt; findnodelist();</code>

從上面的接口,就可以看到,它支援屬性及屬性值過濾,支援屬性名過濾,支援排除性名過濾,包含的文本過濾,包含的節點名過濾,被節點包含的名字過濾,排除子節點名過濾,至少包含一個節點名過濾,至少包含一個屬性過濾,節點名過濾,這些過濾條件是可以組合使用的。

有了這麼強大的節點過濾功能,程式員們對于xml的使用就簡單便捷多了。