XML解析(Dom4j)

来源:互联网 发布:杜老师的c编程密码 编辑:程序博客网 时间:2024/05/21 15:05

Dom(文档对象模型(Document Object Model))

W3C 文档对象模型 (DOM) 是中立于平台和语言的接口(可用于任何编程语言),它允许程序和脚本动态地访问和更新文档的内容、结构和样式。Dom的特点:将文档一次性加入到内存,并解析为树状结构的数据。所以说Dom只适合于解析相对较小的文件,不然的话一次性读入到内存中,将很容易造成内存溢出。    整个文档是一个文档节点    每个 HTML 标签是一个元素节点    包含在 HTML 元素中的文本是文本节点    每一个 HTML 属性是一个属性节点    注释属于注释节点

——————————JAVA——————————
下面举个例子详细说明:用Dom4j解析people.xml文件
总结下,学习过程中遇到的小坑:
1.因为我创建的是一个maven项目,当时就是把people.xml放在代码文件一起,同一级目录下的,后来,始终都报null Nested exception,找不到对应的xml文件,才知道maven项目,非.java结尾的文件,放到src/main/java文件中都会找不着,必须对应的放到resource中去。
2.Collections.sort(people,(o1, o2) -> o1.getName().compareTo(o2.getName()));当name是中文字符的时候,这种方法的比较可能并不会得到我们想要的答案,我们需要利用Collactor来进行比较。如果需要使用特定地点的比较规则,则需要使用Collator.getInstance(Locale desiredLocale).

Collections.sort(people,(o1, o2) -> Collator.getInstance().compare(o1.getName(),o2.getName()));

先看一下people.xml文件:
people.xml
第一步:生成saxreader对象,

SAXReader saxReader = new SAXReader();

第二步:生成document对象

Document document = saxReader.read(DomTest.class.getClassLoader().getResourceAsStream("com/bigdata/BBTree/people.xml"));

第三步:获取根节点

Element root =  document.getRootElement();

第四步:获取根节点的子节点,返回值是一个list列表。

List<Element> el = root.elements();

对于Element,我们可以调用elements()方法,得到它的所有子节点。
一步步递归下去,就能得到所有的节点。

List<Element> el = root.elements();    for (Element e:el) { }

将每一步得到的结果进行输出,就可以得出树的大概结构。

这里写图片描述

那么我们通过遍历就能解析出每个节点的数据,从而进行对应的操作。

List<Person> people = new ArrayList<>();    Person p;    for (Element e:el) {        String name = e.element("name").getText();        int age = Integer.valueOf(e.elementText("age"));        String tel = e.elementText("tel");        p= new Person(name,age,tel);        people.add(p);    }    System.out.println(people);

——————————PYTHON——————————

对于python中使用dom4j,和java相比较就是换汤不换药。
首先需要的是,
1.手动导入模块:

from xml.dom.minidom import parse

2.运用导入的模块,生成document对象,此处people.xml跟python文件放用一级目录即可。

doc=parse("people.xml")

3.获取根节点:

e=doc.documentElement

4.根据tag获取各个节点信息,返回一个列表,可使用index访问具体某一个元素.

ps=e.getElementsByTagName("person")nm=e.getElementsByTagName("name")[0]

这个时候就将xml中的数据解析出来了。不过通过对比,我感觉这棵树,和我们用java解析出来的那棵树还是不同的,具体我们来看下。
子节点运行结果
由图中运行结果可以看出,第一个Person元素的子节点就有7个,4个text node,3个element。这让我很是纳闷,捣鼓了好一会终于发现了,原来所谓的element元素就是写在尖括号中,也就是标签,而Text Node指的是写在外面的text,看下面这张图:
tree
4个text node节点分别为元素节点和元素节点之间的回车换行和空格,
3个Element节点为name,age,tel三个元素。
而对于name节点而言,它的子节点就是一个Text node,zhangsan,这么一想,树的结构就清晰多啦。

下面就可以对解析出来的数据做处理啦:

people=[]ps=e.getElementsByTagName("person")for p in ps:    name=p.getElementsByTagName("name")[0].childNodes[0].data    age=p.getElementsByTagName("age")[0].childNodes[0].data    tel=p.getElementsByTagName("tel")[0].childNodes[0].data    p=Person(name,age,tel)    people.append(p)print(people)for p in sorted(people,key=lambda i:i.age ):    print(p)people.sort(key=lambda p:p.name,reverse=True)print(people)

总体来说还是比较简单,但是因为是一次性读取文件,所以在使用上只适用于小文件的解析,有一定的局限性,需要导入jar包才能使用。

原创粉丝点击