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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 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支持单标签。

相关文章
|
26天前
|
XML 数据采集 数据格式
Python 爬虫必备杀器,xpath 解析 HTML
【11月更文挑战第17天】XPath 是一种用于在 XML 和 HTML 文档中定位节点的语言,通过路径表达式选取节点或节点集。它不仅适用于 XML,也广泛应用于 HTML 解析。基本语法包括标签名、属性、层级关系等的选择,如 `//p` 选择所有段落标签,`//a[@href=&#39;example.com&#39;]` 选择特定链接。在 Python 中,常用 lxml 库结合 XPath 进行网页数据抓取,支持高效解析与复杂信息提取。高级技巧涵盖轴的使用和函数应用,如 `contains()` 用于模糊匹配。
|
1月前
|
XML JavaScript 前端开发
如何解析一个 HTML 文本
【10月更文挑战第23天】在实际应用中,根据具体的需求和场景,我们可以灵活选择解析方法,并结合其他相关技术来实现高效、准确的 HTML 解析。随着网页技术的不断发展,解析 HTML 文本的方法也在不断更新和完善,
|
1月前
|
JavaScript API 开发工具
<大厂实战场景> ~ Flutter&鸿蒙next 解析后端返回的 HTML 数据详解
本文介绍了如何在 Flutter 中解析后端返回的 HTML 数据。首先解释了 HTML 解析的概念,然后详细介绍了使用 `http` 和 `html` 库的步骤,包括添加依赖、获取 HTML 数据、解析 HTML 内容和在 Flutter UI 中显示解析结果。通过具体的代码示例,展示了如何从 URL 获取 HTML 并提取特定信息,如链接列表。希望本文能帮助你在 Flutter 应用中更好地处理 HTML 数据。
122 1
|
2月前
|
XML 数据格式
HTML 实例解析
本文介绍了HTML中常见元素的使用方法,包括`&lt;p&gt;`、`&lt;body&gt;`和`&lt;html&gt;`等。详细解析了这些元素的结构和作用,并强调了正确使用结束标签的重要性。此外,还提到了空元素的使用及大小写标签的规范。
|
2月前
|
XML 前端开发 数据格式
Beautiful Soup 解析html | python小知识
在数据驱动的时代,网页数据是非常宝贵的资源。很多时候我们需要从网页上提取数据,进行分析和处理。Beautiful Soup 是一个非常流行的 Python 库,可以帮助我们轻松地解析和提取网页中的数据。本文将详细介绍 Beautiful Soup 的基础知识和常用操作,帮助初学者快速入门和精通这一强大的工具。【10月更文挑战第11天】
75 2
|
2月前
|
XML JavaScript 数据格式
XML DOM 遍历节点树
XML DOM 遍历节点树
|
2月前
|
XML Web App开发 JavaScript
XML DOM 解析器
XML DOM 解析器
|
2月前
|
XML Web App开发 JavaScript
XML DOM 解析器
XML DOM 解析器
|
2月前
|
XML JavaScript 数据格式
XML DOM 遍历节点树
XML DOM 遍历节点树
|
2月前
|
XML 前端开发 Java
讲解SSM的xml文件
本文详细介绍了SSM框架中的xml配置文件,包括springMVC.xml和applicationContext.xml,涉及组件扫描、数据源配置、事务管理、MyBatis集成以及Spring MVC的视图解析器配置。
79 1

热门文章

最新文章

推荐镜像

更多