优点:
高效、简单、易用的Xml解析器。
学习时间,分分钟。
解析速度超过,查找速度超快,支持格式化。
缺点:不支持Xml Schema,DTD校验。
Maven引用坐标:
<dependency> <groupId>org.tinygroup</groupId> <artifactId>xmlparser</artifactId> <version>0.0.12</version> </dependency>
解析下面xml
<?xml version="1.0"?> <students> <student> <name>John</name> <grade>B</grade> <age>12</age> </student> <student> <name>Mary</name> <grade>A</grade> <age>11</age> </student> <student> <name>Simon</name> <grade>A</grade> <age>18</age> </student> </students>
示例代码:
public class TestXmlParser { public static void main(String[] args) throws Throwable { File file = new File("E:/test/students.xml "); XmlStringParser parser = new XmlStringParser(); XmlDocument document = parser.parse(IoUtils.readFromInputStream( new FileInputStream(file),"utf-8")); printStudents(document.getRoot()); } private static void printStudents(XmlNode studentsNode) { for(XmlNode studentNode:studentsNode.getSubNodes("student")){ printStuent(studentNode); } } private static void printStuent(XmlNode studentNode) { printSubTagByName(studentNode,"name"); printSubTagByName(studentNode,"grade"); printSubTagByName(studentNode,"age"); } private static void printSubTagByName(XmlNode studentNode,String tagName) { System.out.println( studentNode.getSubNode(tagName).getContent()); } }
格式化示例:
XmlDocument doc; doc = new XmlStringParser() .parse("<html 中='文'><head><title>aaa</title></head></html>"); XmlFormater f = new XmlFormater(); System.out.println(f.format(doc));运行结果:
<html 中="文"> <head> <title> aaa </title> </head> </html>性能测试:
构建下面的节点规模:
HtmlNode node = null; public NameFilterTest() { node = new HtmlNode("root"); for (int i = 0; i < 60; i++) { HtmlNode a = node.addNode(new HtmlNode("a" + i)); for (int j = 0; j < 60; j++) { HtmlNode b = a.addNode(new HtmlNode("b" + j)); for (int k = 0; k < 60; k++) { b.addNode(new HtmlNode("c" + k)); } } } }
也就是节点数60+60*60+60*60*60个节点数时,进行下面的查找:
long t21 = System.currentTimeMillis(); FastNameFilter fast = new FastNameFilter(node); long t22 = System.currentTimeMillis(); System.out.println("fast初始化用时" + (t22 - t21)); long t1 = System.currentTimeMillis(); String nodeName = null; for (int x = 0; x < 10000; x++) { nodeName = fast.findNode("b6").getNodeName(); } long t2 = System.currentTimeMillis(); System.out.println("FastNameFilter用时" + (t2 - t1));
运行结果:
fast初始化用时130 FastNameFilter用时39也就是说在219661个节点规模下,查找指定节点10000次,只用时39ms,还有比这个更快的么?
如果到此为止,其实也没有啥,它提供的过滤功能可以满足绝大多数的应用场景,先看看接口:
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(); }
有了这么强大的节点过滤功能,程序员们对于Xml的使用就简单便捷多了。