不一样的味道--Html及Xml解析、格式化、遍历

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

TinyXmlParser一切以简单、实用、快速为主。

示例1:Xml字符串解析

比如,我们要解析一段Xml字符串,简单如下即可:

?
1
XmlDocument xmlDocument = new XmlStringParser().parse( "<title><a>a</a></title>" );

示例2:输出格式化后的Xml:

?
1
2
XmlFormater formater = new XmlFormater();
System.out.println(formater.format(xmlDocument));

运行结果如下:

?
1
2
3
< title >
   < a >a</ a >
</ title >

当然换一种写法也是可以的,比如下面:

?
1
2
3
XmlDocument xmlDocument = new XmlStringParser().parse("< title >< a >a</ a ></ title >");
XmlFormater formater = new XmlFormater();
System.out.println(formater.format(xmlDocument));
输出结果和上面是一样的。

示例3:中文标签支持

?
1
2
3
4
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);

上面的例子用了两种方式,一种是非格式化方式输出,默认是用一行输出的;另一种是格式化输出的:

?
1
2
3
4
5
6
7
<html 中= "文" ><head><title>aaa</title><中>中信</中></head></html>
<html 中= "文" >
   <head>
     <title>aaa</title>
     <中>中信</中>
   </head>
</html>

可以看到对于中文标签及属性也有完美支持。

示例4:容错性示例

?
1
2
3
XmlDocument document = new XmlStringParser().parse( "<title><a>a</title>" );
XmlFormater formater = new XmlFormater();
formater.format(document, System.out);

上面的例子中,<a> 标签没有</a>结束标签。

输出结果如下:

?
1
2
3
< title >
   < a >a</ a >
</ title >

可以看到,它已经尽最大可能来猜测是否正确

示例5:性能测试

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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树

?
1
2
3
4
5
6
7
8
9
10
11
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));

运行结果如下:

?
1
2
初始化用时:48
遍历用时:20

请注意,上面的时间单位不是分钟,不是秒钟,而是毫秒。

示例6:节点过滤

对节点过滤是否方便才是最紧要的。这个功能,太过强大,因此,用例子已经演示不出它的强大了。直接贴接口:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
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();
}

也就是说它支持节点指定属性名及指定属性值过滤(可以指定多组)、指定属性名过滤(不管是什么值都可以,可以指定多个)、可以指定排除属性及属性值(即不能包含的属性名及值,可以包含多组)、不能包含的属性(可以包含多组)、包含文本内容(可以指定多组)、不能包含的文件内容(可以指定多组),可以指定包含的节点名(可以指定多组)、可以指定不能包含的节点(可以指定多组)、可以指定必须在某个节点下(可以指定多组)、可以指定不能在某个节点下(可以指定多组)、可以指定至少包含某几个节点中的一个,可以指定至下包含某几个属性中的一个,可以根据节点名进行搜索。

上面的所有条件可以组合起来一起搜索。

说了这么多,看看测试用例:

?
1
2
3
4
5
6
7
8
9
10
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树:

?
1
2
3
4
5
6
7
8
9
10
<root>
   <aa a= "av" b= "bv" >
     <a>
     </a>
   </aa>
   <aa a= "av1" b= "bv1" c= "cv1" >
     <b>
     </b>
   </aa>
</root>

下面是一堆的测试用例了:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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支持单标签。

相关文章
|
4天前
|
XML JavaScript 数据格式
XML DOM 遍历节点树
在处理XML文档时,我们常需提取各元素值,这时就要用到XML DOM的节点树遍历功能。以下示例展示了如何遍历根元素的所有子节点,并输出它们的名称和值:例如 &quot;title: Everyday Italian&quot;,&quot;author: Giada De Laurentiis&quot; 和 &quot;year: 2005&quot;。实现步骤包括:加载XML字符串到xmlDoc对象,获取根元素子节点,最后输出每个子节点的名称与文本节点的值。
|
6天前
|
XML JavaScript Java
【JAVA XML 探秘】DOM、SAX、StAX:揭秘 Java 中 XML 解析技术的终极指南!
【8月更文挑战第25天】本文详细探讨了Java中三种主流的XML解析技术:DOM、SAX与StAX。DOM将XML文档转换为树状结构,便于全方位访问和修改;SAX采取事件驱动模式,适用于大型文件的顺序处理;StAX则兼具DOM和SAX的优点,支持流式处理和随机访问。文中提供了每种技术的示例代码,帮助读者理解如何在实际项目中应用这些解析方法。
34 1
|
2天前
|
XML Web App开发 JavaScript
XML DOM 解析器
XML DOM 解析器
|
2天前
|
XML JavaScript 数据格式
XML DOM 遍历节点树
XML DOM 遍历节点树
|
4天前
|
XML Web App开发 JavaScript
XML DOM 解析器
XML DOM解析器是内置在大多数浏览器中的工具,用于读取和操作XML文档。它将XML数据转换成JavaScript可访问的XML DOM对象。DOM提供了一系列方法和函数来遍历、访问、插入和删除XML树的节点。在处理XML文档前,需要先加载它到DOM对象中。示例如下:通过条件判断创建XMLHTTP对象,打开并发送请求获取XML文件内容,最后将服务器响应设置为XML DOM对象以便后续处理。
|
8天前
|
XML JavaScript 数据格式
XML DOM 遍历节点树
在处理XML文档时,我们常需提取各元素值,这时就要用到XML DOM的节点树遍历功能。以下示例展示了如何遍历根元素的所有子节点,并输出它们的名称和值:例如 &quot;title: Everyday Italian&quot;,&quot;author: Giada De Laurentiis&quot; 等。
|
8天前
|
XML Web App开发 JavaScript
XML DOM 解析器
XML DOM解析器是内置在大多数浏览器中的工具,用于读取和操作XML文档。它将XML数据转换成JavaScript可访问的XML DOM对象。DOM提供了一系列方法和函数来遍历、访问、插入和删除XML树的节点。在处理XML文档前,需要先加载到DOM中。示例代码展示了如何通过XMLHTTP对象加载并设置&quot;books.xml&quot;为XML DOM对象以供后续操作。
|
2天前
|
XML 存储 JavaScript
xml介绍与解析,及xml库包使用
xml介绍与解析,及xml库包使用
7 0
|
6天前
|
XML Web App开发 JavaScript
XML DOM 解析器
XML DOM解析器是内置在大多数浏览器中的工具,用于读取和操作XML文档。它将XML数据转换成XML DOM对象,使JavaScript能够访问和处理这些数据。DOM解析器提供了一系列方法来遍历、访问、插入和删除XML树中的节点。为了操作XML文档,首先需要加载文档到DOM对象中。示例代码展示了如何通过XMLHTTP请求加载一个名为&quot;books.xml&quot;的XML文件,并将其设置为XML DOM对象以供后续处理。
|
6天前
|
XML JavaScript 数据格式
XML DOM 遍历节点树
在处理XML文档时,我们常需提取各元素值,这时就要用到XML DOM的节点树遍历功能。以下示例展示了如何遍历根元素的所有子节点,并输出它们的名称和值:例如 &quot;title: Everyday Italian&quot;,&quot;author: Giada De Laurentiis&quot; 等。

推荐镜像

更多
下一篇
云函数