更多内容查看官网: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支持单标签。