零碎笔记02-关于xml类型文件的解析整理

零碎笔记02-关于xml类型文件的解析整理

1.xml文档

1.1 什么是xml文档

MDN的解释:

XML(Extensible Markup Language)是一种类似于 HTML,但是没有使用预定义标记的语言。因此,可以根据自己的设计需求定义专属的标记。这是一种强大将数据存储在一个可以存储、搜索和共享的格式中的方法。最重要的是,因为 XML 的基本格式是标准化的,如果你在本地或互联网上跨系统或平台共享或传输 XML,由于标准化的 XML 语法,接收者仍然可以解析数据。

菜鸟教程的解释:

XML 指可扩展标记语言(eXtensible Markup Language)。XML 被设计用来传输和存储数据,不用于表现和展示数据,HTML 则用来表现数据。XML 很重要,也很容易学习。

简单来说,xml就是一个类似与HTML的语言,它本身没有像HTML一样存在预设的标签标记,我们可以在里面自由定义类似<test></test>的标记,由这种自定义标记组成的文档,就是xml文档,它可以传输和存储数据,也正因如此,一般这种文档也是需要具有相应结构规范的。信息不宜太过杂乱,否则解析就会变得很麻烦。

上面说xml本身是没有预设标签标记的,但有时我们需要在项目的内置的xml进行一些标记的添加,自定义标记就会报错,因为它遵循了某个规范,来保证项目可以正常运行,自定义标记是无法被该规范解析,就会报错。具体为何下面讲解xml解析之后就可以理解了。

1.2 xml的节点

在1.1里我们知道xml文档可以用于数据的传输和存储,我们如何得到数据呢?这时候我们就需要了解节点了。和HTML一样,当我们想在js中获取某个元素的值的时候我们就需要通过document.getElementBy…()类似的方法来获取该元素,然后再去得到该元素的某个值,这个元素就是一个节点。在xml中也是一样的,我们想要得到值就要获取该节点。我们在xml里定义的 <test></test> 标记就是节点。

2.解析xml

2.1 工具

我们解析xml文件需要使用到 dom4j 的jar包,这个我们可以去官网下载,地址在这里:dom4j

请添加图片描述

2.2 解析过程

2.2.1 文件路径

在java中我们要解析xml,首先需要得到文件路径,在这里就需要使用到File类。

File file = new File("D://xmljson//citys.xml");
2.2.2 解析器

要解析xml文件,我们要使用刚刚导入的 dom4j的jar包里的解析器

// 创建DOM4J解析器
SAXReader sax = new SAXReader();
2.2.3 文件解析

在这里我使用的例子是省市县信息的xml文件,以下是文件的大体结构

在这里插入图片描述

红色箭头是节点<mapping>的子节点,蓝色箭头是红色箭头指向的<countries>的子节点,绿色就是蓝色箭头指向的<regions>的子节点。

结构我们分析完了,我们来看怎么获取节点。

我们先要获取文档,就要通过刚刚创建的解析器sax读取文件,然后使用document来接收此文件。接着我们通过document.getRootElement()来获取此文件的根节点,再然后我们想获取根节点的子节点,就通过elements()方法来获取。

代码如下:

		Document document = null;
		try {
			document = sax.read(file); // 读取文件
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Element root = document.getRootElement();// 获取文件的根节点
		List<Element> list = root.elements();// 获取根节点的子节点

运行结果:

运行结果

从结果可以看出:<mapping>是根节点,<countries>是根节点的子节点,虽然使用了集合list接收,但其实在此文件中<mapping>节点下只有一个<countries>子节点。不过,由此我们应该能反应过来了,我们用集合接收子节点,说明我们要得到这些子节点的话就需要使用循环了。

所以紧接着我们遍历list:

for (int j = 0; j < list.size(); j++) {
		if (list.get(j).getName().equals("countries")) {	// 判断节点是否为国家
				List<Element> regionList = list.get(j).elements();	// 此国家节点信息集合,因为此次则更注重于省份,我命名为了regionlist
				for (int k = 0; k < regionList.size(); k++) {	// 遍历此国家节点

ps:我虽然命名为regionList,但是其中不是只包含了region的信息,只是因为我此次更侧重于这方面的信息,所以这样子取名,个人习惯,无需在意

list.get(j)就是遍历的子节点,我们通过getName方法来获取节点的名字。所以上面的操作就是判断节点名称是否为countries,如果是true则再创建一个regionList接收countries下的所有子节点。

然后我们再判断子节点里的节点是否为省级节点,再遍历。之后都如此类推。

记住,在省级节点里,除了需要遍历市级节点,我们还需要将省id,省code,省name都作为省对象封装起来,准备随着后续跟着循环被添加进数据库。包括之后的市级信息,区县级信息都是如此。

	if (regionList.get(k).getName().equals("regions")) {	// 判断节点是否为省级节点
		List<Element> info = regionList.get(k).elements();	// 省级节点的子节点集合
		List<Province> list2 = new ArrayList<Province>();	// 创建集合接收省份信息
		for (int m = 0; m < info.size(); m++) {	// 遍历省级节点的子节点
			if (info.get(m).getName().equals("id")) {	// 判断是否为省节点id
				//	System.out.println(info.get(m).getText()); 
				pro_id = Integer.valueOf(info.get(m).getText());
			}
			//	System.out.println("===========1==========");
			if (info.get(m).getName().equals("code")) {	// 判断是否为省节点code
				//	System.out.println(info.get(m).getText());
				pro_code = info.get(m).getText();
			}

整个xml文件的解析逻辑就是这样。

下面贴下我的完整代码:

package com.it.parsemain;

import java.io.File;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.it.dao.InsertCityDao;
import com.it.dao.InsertDistrictDao;
import com.it.dao.InsertProvinceDao;
import com.it.pojo.City;
import com.it.pojo.District;
import com.it.pojo.Province;

public class XmlParseMain {
	public static void main(String[] args) {
		File file = new File("D://xmljson//citys.xml");
		
		// 创建DOM4J解析器
		SAXReader sax = new SAXReader();
		try {
			Document document = sax.read(file);
			Element root = document.getRootElement();
			List<Element> list1 = root.elements();
			// 省信息
			Integer pro_id = null;
			String pro_code = null;
			String pro_name = null;
			// 市信息
			String city_id = null;
			String city_name = null;
			// 地区信息
			String d_id = null;
			String d_name = null;
			for (int j = 0; j < list1.size(); j++) {
				if (list1.get(j).getName().equals("countries")) {	// 判断节点是否为国家
					List<Element> regionList = list1.get(j).elements();	// 此国家节点信息集合,因为此次则更注重于省份,我命名为了regionlist
					for (int k = 0; k < regionList.size(); k++) {	// 遍历此国家节点
						// System.out.println(regionList.get(k).getName());
						if (regionList.get(k).getName().equals("regions")) {	// 判断节点是否为省级节点
							List<Element> info = regionList.get(k).elements();	// 省级节点的子节点集合
							Queue<Province> list2 = new LinkedList<Province>();	// 创建集合接收省份信息
							for (int m = 0; m < info.size(); m++) {	// 遍历省级节点的子节点
								if (info.get(m).getName().equals("id")) {	// 判断是否为省节点id
									//	System.out.println(info.get(m).getText()); 
									pro_id = Integer.valueOf(info.get(m).getText());
								}
								//	System.out.println("===========1==========");
								if (info.get(m).getName().equals("code")) {	// 判断是否为省节点code
									//	System.out.println(info.get(m).getText());
									pro_code = info.get(m).getText();
								}
								//	System.out.println("===========2==========");
								if (info.get(m).getName().equals("cn")) {	// 判断是否为省节点中文名
									// System.out.println(info.get(m).getText());
									pro_name = info.get(m).getText();
								}
								if (info.get(m).getName().equals("cities")) {	// 判断是否为市级节点
									List<Element> cityList = info.get(m).elements();	// 市级节点的子节点集合
									Queue<City> list3 = new LinkedList<City>();
									for (int l = 0; l < cityList.size(); l++) {	// 遍历市级节点的子节点
										//	System.out.println(cityList.get(l).getName());
										if (cityList.get(l).getName().equals("id")) {	// 判断是否为市节点id
											//	System.out.println("========"+cityList.get(l).getText()); 
											 	city_id = (String) (pro_code+String.format("%02d", Integer.valueOf(cityList.get(l).getText())));
											 	System.out.println(city_id);
										}
										//	System.out.println("===========1==========");
										if (cityList.get(l).getName().equals("cn")) {	// 判断是否为市节点名字
											//	System.out.println(cityList.get(l).getText());
												city_name = cityList.get(l).getText();
										}
										if (cityList.get(l).getName().equals("districts")) {
											List<Element> dList = cityList.get(l).elements();
											Queue<District> list4 = new LinkedList<District>();
											for (int n = 0; n < dList.size(); n++) {
												if (dList.get(n).getName().equals("id")) {	// 判断是否为区县节点id
													//	System.out.println("========"+cityList.get(l).getText()); 
													 	d_id = (String) (city_id+String.format("%02d", Integer.valueOf(dList.get(n).getText())));
													 	// System.out.println(d_id);
												}
												//	System.out.println("===========1==========");
												if (dList.get(n).getName().equals("cn")) {	// 判断是否为区县节点名字
													//	System.out.println(cityList.get(l).getText());
														d_name = dList.get(n).getText();
												}
											}
											District district = new District(d_id, d_name, city_id);
											list4.add(district);
											System.out.println(list4);
											try {
												new InsertDistrictDao().add(list4);
											} catch (SQLException e) {
												// TODO Auto-generated catch block
												e.printStackTrace();
											}
										}
									}
									City city = new City(city_id, city_name, pro_id);
									list3.add(city);
									System.out.println(list3);
									try {
										new InsertCityDao().add(list3);
									} catch (SQLException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}
									
								}
							}
							Province province = new Province(pro_id, pro_code, pro_name);// 创建省份实体对象
							list2.add(province);	// 添加省份信息到集合
							System.out.println(list2);
							try {
								new InsertProvinceDao().add(list2);	// 调用添加省份方法
							} catch (SQLException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
					}
				}
			}
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

以上是我的一些见解,如有错误欢迎指正。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值