標籤:xml html parser 開發架構 tiny
更多內容查看官網:http://www.tinygroup.org
TinyXmlParser一切以簡單、實用、快速為主。
樣本1:Xml字串解析
比如,我們要解析一段Xml字串,簡單如下即可:
XmlDocument xmlDocument = new XmlStringParser().parse("<title><a>a</a></title>");樣本2:輸出格式化後的Xml:
XmlFormater formater = new XmlFormater();System.out.println(formater.format(xmlDocument));
運行結果如下:
<title> <a>a</a></title>
當然換一種寫法也是可以的,比如下面:
XmlDocument xmlDocument = new XmlStringParser().parse("<title><a>a</a></title>");XmlFormater formater = new XmlFormater();formater.format(xmlDocument,System.out));輸出結果和上面是一樣的。樣本3:中文標籤支援
XmlDocument document = new XmlStringParser().parse("<html 中=‘文‘><head><title>aaa</title><中>中信</中></head></html>");document.write(System.out);XmlFormater formater = new XmlFormater();formater.format(document, System.out);
上面的例子用了兩種方式,一種是非格式化方式輸出,預設是用一行輸出的;另一種是格式化輸出的:
<html 中="文"><head><title>aaa</title><中>中信</中></head></html><html 中="文"> <head> <title>aaa</title> <中>中信</中> </head></html>
可以看到對於中文標籤及屬性也有完美支援。
樣本4:容錯性樣本
XmlDocument document = new XmlStringParser().parse("<title><a>a</title>");XmlFormater formater = new XmlFormater();formater.format(document, System.out);
上面的例子中,<a> 標籤沒有</a>結束標籤。
輸出結果如下:
<title> <a>a</a></title>
可以看到,它已經盡最大可能來猜測是否正確
樣本5:效能測試
XmlNode node = null;public NameFilterTest() {node = new XmlNode("root");for (int i = 0; i < 60; i++) {XmlNode a = node.addNode(new XmlNode("a" + i));for (int j = 0; j < 60; j++) {XmlNode b = a.addNode(new XmlNode("b" + j));for (int k = 0; k < 60; k++) {b.addNode(new XmlNode("c" + k));}}}}
構建這麼大一棵Dom樹
long t21 = System.currentTimeMillis();FastNameFilter<XmlNode> fast = new FastNameFilter(node);long t22 = System.currentTimeMillis();System.out.println("初始化用時:" + (t22 - t21));long t1 = System.currentTimeMillis();for (int x = 0; x < 10000; x++) { XmlNode node = fast.findNode("b6");}// System.out.println(nodeName);long t2 = System.currentTimeMillis();System.out.println("遍曆用時:" + (t2 - t1));
運行結果如下:
初始化用時:48遍曆用時:20
請注意,上面的時間單位不是分鐘,不是秒鐘,而是毫秒。
樣本6:節點過濾
對節點過濾是否方便才是最緊要的。這個功能,太過強大,因此,用例子已經示範不出它的強大了。直接貼介面:
public interface NodeFilter<T extends Node<T>> {/** * 初始化節點 * * @param node */void init(T node);/** * 設定必須包含的屬性及對應屬性的值,必須存在 * * @param includeAttributes */void setIncludeAttribute(Map<String, String> includeAttributes);/** * 設定必須包含的屬性及對應的屬性的值,必須存在 * * @param key * @param value */void setIncludeAttribute(String key, String value);/** * 設定必須包含的屬性 * * @param includeAttribute */void setIncludeAttributes(String... includeAttribute);/** * 設定必須排除的屬性及對應屬性值 如果包含屬性,但屬性的值與Map中不相同,允許存在該屬性 若包含屬性且屬性的值與Map中相同,則不允許存在該屬性 * * @param excludeAttribute */void setExcludeAttribute(Map<String, String> excludeAttribute);/** * 設定必須排除的屬性,指定的屬性不能存在 * * @param excludeAttribute */void setExcludeAttribute(String... excludeAttribute);/** * 設定必須包含的內容,只需要context中包include該值就行 * * @param includeText */void setIncludeText(String... includeText);/** * 設定必須排除的內容 * * @param excludeText */void setExcludeText(String... excludeText);/** * 設定必須包含的子節點 * * @param includeNode */void setIncludeNode(String... includeNode);/** * 設定父節點不允許的節點名稱 * * @param excludeByNode */void setExcludeByNode(String... excludeByNode);/** * 設定父節點必須包含的節點名稱 * * @param includeByNode */void setIncludeByNode(String... includeByNode);/** * 設定必須排除的子節點 * * @param excludeNode */void setExcludeNode(String... excludeNode);/** * 設定至少包含一個指定名稱的節點 * * @param xorSubNode */void setXorSubNode(String... xorSubNode);/** * 設定至少包含一個指定名稱屬性 * * @param xorProperties */void setXorProperties(String... xorProperties);/** * 清除過濾條件 */void clearCondition();/** * 設定要搜尋的節點名稱 */void setNodeName(String nodeName);/** * 尋找指定節點名稱及滿足其他條件的節點列表 * * @param nodeName * @return */List<T> findNodeList(String nodeName);/** * 根據名字及其他條件尋找節點,如果有多個,也只返回第一個 * * @param nodeName * 要尋找的節點名稱 * @return */T findNode(String nodeName);/** * 搜尋符合設定的節點名稱的節點,如果有多個,則只返回找到的第一個 * * @return */T findNode();/** * 搜尋符合設定的節點名稱的節點列表 * * @return */List<T> findNodeList();}
也就是說它支援節點指定屬性名稱及指定屬性值過濾(可以指定多組)、指定屬性名稱過濾(不管是什麼值都可以,可以指定多個)、可以指定排除屬性及屬性值(即不能包含的屬性名稱及值,可以包含多組)、不能包含的屬性(可以包含多組)、包含常值內容(可以指定多組)、不能包含的檔案內容(可以指定多組),可以指定包含的節點名(可以指定多組)、可以指定不能包含的節點(可以指定多組)、可以指定必須在某個節點下(可以指定多組)、可以指定不能在某個節點下(可以指定多組)、可以指定至少包含某幾個節點中的一個,可以指定至下包含某幾個屬性中的一個,可以根據節點名進行搜尋。
上面的所有條件可以組合起來一起搜尋。
說了這麼多,看看測試案例:
node = new XmlNode("root");XmlNode n1 = node.addNode(new XmlNode("aa"));n1.setAttribute("a", "av");n1.setAttribute("b", "bv");n1.addNode(new XmlNode("a"));n1 = node.addNode(new XmlNode("aa"));n1.setAttribute("a", "av1");n1.setAttribute("b", "bv1");n1.setAttribute("c", "cv1");n1.addNode(new XmlNode("b"));
上面構建了一棵Dom樹:
<root> <aa a="av" b="bv"> <a> </a> </aa> <aa a="av1" b="bv1" c="cv1"> <b> </b> </aa></root>
下面是一堆的測試案例了:
filter = new NameFilter(node);filter.clearCondition();assertEquals(1, filter.findNodeList("root").size());filter.setExcludeAttribute("c");assertEquals(1, filter.findNodeList("aa").size());// 測試包含屬性名稱filter.clearCondition();assertEquals(1, filter.findNodeList("root").size());filter.setIncludeAttributes("c");assertEquals(1, filter.findNodeList("aa").size());// 測試包含指定屬性值filter.clearCondition();Hashtable<String, String> pht = new Hashtable<String, String>();pht.put("a", "av1");filter.setIncludeAttribute(pht);assertEquals(1, filter.findNodeList("aa").size());filter.setExcludeAttribute("c");assertEquals(0, filter.findNodeList("aa").size());// 測試包含指定節點filter.clearCondition();filter.setIncludeNode("a");assertEquals(1, filter.findNodeList("aa").size());filter.setIncludeAttributes("c");assertEquals(0, filter.findNodeList("aa").size());// 測試包含指定節點filter.clearCondition();filter.setExcludeNode("c");assertEquals(2, filter.findNodeList("aa").size());
測試案例寫得比較醜,但是對它的使用還是做了一個簡單的示範。
上面所有的例子當中,把X變成Ht,就是針對Html解析器的了,API完全一致,用法完全相同。
區別在於Xml的標籤及屬性名稱是大小寫敏感的,而Html是大小寫不敏感的。
另外Html支援單標籤。