JAVA操作xml文件

参考:java操作xml方法,总有适合你的
XML技术在Java开发中的应用

1、简介

xml: extensible Markup Language

1.1使用场景:

	不同的系统之间交互时使用xml数据传输,目前主要使用json
	作为框架的配置文件
	存储数据

1.2XML特点:

平台无关性
90%的语言都支持xml
xml具有自我描述性,(内容自定义)
	html文件中,所有元素(标签)都是官方定义好的,我们直接引用
	xml文件中,所有元素自定义

1.3xml语法

文档声明<?xml version="1.0" encoding="UTF-8"?>
XML必须有根元素
xml元素(标签)有开必有合(结束标签)
xml元素对大小写敏感
xml元素必须正确的嵌套
xml元素的属性必须加引号(单引号双引号都可以)

1.4 CDATA区

处理xml文件中的特殊字符
在xml文件中写特殊符号是,报错,忽略其本性,编程普通的字符串<socre><![CDATA[成绩<60]]></socre>	
<?xml version="1.0" encoding="UTF-8"?>
<!-- 
	这是注释
	定义一个xml文件,描述自己的家庭
	家庭成员
	每个人都有姓名职业
-->
<class>
	<student duty="班长" >
		<id>1</id>
		<name>张三</name>
		<socre><![CDATA[成绩<60]]></socre>		
	</student>
</class>

1.5 DTD文件

DTD: document Type Definiton
DTD的目的是帮助你编写合法的代码
DTD和xml之间的关系
类(人类)和对象(我)的关系
数据库的表和行(一条记录),dtd相当于设计表,xml相当是表中数据

下面代码的意思是根目录下有n个student元素,student元素下有name和age两个元素,其中name元素为字符串类型,age也是字符串类型

<!ELEMENT students (student*)>
<!ELEMENT student (name,age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>

在xml中引用

<?xml version="1.0" encoding="UTF-8"?>
<!-- 下面语句就是引用dtd文件 -->
<!DOCTYPE students SYSTEM "demon.dtd">
<!-- 
	这是注释
	定义一个xml文件,描述自己的家庭
	家庭成员
	每个人都有姓名职业
-->
<students>
	<student>
		<name></name>
		<age></age>
	</student>
</students>

1.6 xsd

xsd是xml结构定义(XML Schemas Definition)
xsd是dtd替代品,比dtd高端一些
xsd有点:
xsd的代码基于xml没有专门的语法,和xml一样的解析和处理
xsd文件支持一些列的数据类型

下面代码中
xs是命名空间的意思
maxOccurs=“unbounded” 代表相应元素的子元素没有数量限制
type=“xs:string” 代表响应元素数据类型
xs:complexType 当元素中存在多个元素时使用此类型定义
xs:sequence 排序

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="https://www.we.org/2001/xmlSchema"
	targetNamespace="http://www.example.org/demon"
	xmlns:tns="http://www.example.org/demon" elementFormDefault="qualified"> 
	<xs:element name="NBA">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="star" maxOccurs="unbounded">
					<xs:complexType>
						<xs:element name="starname" type="xs:string" />
						<xs:element name="no" type="xs:string" />
						
					</xs:complexType>
				</xs:element>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
</xs:schema>

xml引用

<?xml version="1.0" encoding="UTF-8"?>

<NBA
xmlns=“http://www.w3school.com.cn”
xmlns=“https://www.we.org/2001/xmlSchema”
xsi:schemaLoaction=“http://www.w3school.com.cn demon.xsd”

<star>
	<starname></starname>
	<no></no>
	
</star>
## 1.7读写操作技术总览

在这里插入图片描述

2、术语解释

2.1jaxp

jaxp: java API for xmlProcessing
作用:关注如何找到某个元素的内容,
详细介绍地址:https://docs.oracle.com/javase/8/docs/technotes/guides/xml/
在这里插入图片描述
在这里插入图片描述
dom:document object Model 文档对象模型
w3c: world Wide Web Consortium
sax: simple API for xml

2.2 jaxb:

扩充:json也有很多框架,例如:fastjson,gson,json-lib,jackson等
jaxb: java Architecture for xml binding
作用:关注xml与java object之间的转换
https://docs.oracle.com/javase/8/docs/technotes/guides/xml/jaxb/index.html

在这里插入图片描述

2.3 OXM

xom: object xml mapping 对象与xml之间的映射

3、XML解析

解析XML文件共有四种方式
DOM解析
SAX解析
JDOM解析
DOM4J解析
前两种属于基础方法,是官方提供的与平台无关的解析
后两种属于扩展方法,他们是在基础的方法上扩展出来的,只适用于JAVA平台

3.1 DOM解析

原理:解析XML的时候,把文档中的所有元素按照其出现的层次关系,在内存中构造出树形结构 生成一个Document对象
优点:元素和元素之间保留结构、关系,可以针对元素进行增删改查
缺点:内存压力较大,解析较慢

3.2 SAX

是一种XML解析的替代方法,更加高效解析。他是朱行扫描,边扫描边解析,并且以时间驱动的方式来进行解析,每解析一行都会触发一个事件
优点:不会出现内存溢出问题,可处理大文件
缺点:只能读,不能写

3.3 JDOM

仅适用具体的类,而不用接口,不灵活

3.4 DOM4J

JDOM的一种智能的分支,合并了许多超出基本XML文档的功能
著名的底层框架hibernate就是用dom4来解析

3.5 性能对比

dom4j 性能最高,其次是SAX, dom和jdom表现不好(解析10兆大小的XML文件,就内存溢出了)

解析器

DOM4J 比较简单的XML解析类库
jsoup功能欠打的DOM方式解析的类库,尤其对HTML的解析更加方便

4 XML操作(DOM4J)

4.1XML文件内容

<content>
	<webSite desc="xml视频教程">https://www.baidu.com</webSite>
	<desc desc="xml视频教程">Java 操作xml文件</desc>
	<owner desc="xml视频教程">darly</owner>
	<detail desc="xml视频教程">
		<videos desc="视频列表">
			<video desc="xml视频教程">
				<chapter id="1">1. java操作xml相关技术概览</chapter>
				<chapter id="2">2.dom读写xml</chapter>
			</video>
			<video id="8099" name="httpclient视频教程">
					<chapter id="1">14.发送上传文件的post请求</chapter>
					<chapter id="2">15.为何要绕过HTTS安全认证</chapter>
					<chapter id="2">16.httpclient链接池和通用工具类封装</chapter>
			</video>
		</videos>
		<projects>
			<project>
				<id>1</id>
				<name>学生成绩管理</name>
			</project>
			<project>
				<id>2</id>
				<name>游戏成绩</name>
			</project>
		</projects>
	</detail>
</content>

步骤

  • 创建解析对象
  • 使用解析器对象读取XML文档生产Document对象
  • 根据Document对象获取XML的元素(标签)信息

DOM4j重要API说明

org.dom4j.Document常用方法
Element getRootElement(); 获取XML文档的根节点

org.dom4j.Element常用方法

  • String getName(); 返回标签的名称
  • List elements(); 获取子标签列表
  • String atrributeValae(String name); 获取指定属性名称的属性值
  • String getText(); 获取标签的文本
  • String getData();获取标签文本
  • String elementText(String name); 获取指定名称的子标签的文本返回子标签文本的值
  • String getTextTrim(); 获取标签文本,同时去除空格

Dom4j中getText()和getStringValue()的作用和区别。

 1)二者都是取得标签的文本值,但有一点不同。

     eg: <books><book><title>java</title></book> <book><title>ruby</title></book></books>

          document.selectSingleNode("//books").getText(); //这里输入为空;

           document.selectSingleNode("//books").getStringValue();//这里输出为javaruby;

4.2 获取元素及遍历元素

package xml;
import java.io.InputStream;
import java.util.List;

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

public class Testxml_1 {	
  
	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws Exception {
		// 1.加载xml文件到jvm中,形成数据流
		InputStream xml = Testxml_1.class.getClassLoader().getResourceAsStream("demon1.xml");
		
		//2、创建解析对象
		SAXReader sax= new SAXReader();
		
		//3、获取文档对象(整过xml文件)[将数据流转换成一个文档对象]
		Document doc = sax.read(xml);
		
		//4. 获得根元素
		
		Element root = doc.getRootElement();
		//5.获得根元素下的所有子元素
		List<Element>  list = root.elements();
		// 与上句作用相同,这里只是体现列表的一种定义方式,使用?代表列表元素类型根据上下文自动定义
//		List<?> list=root.elements();      
//		System.out.println(list.size());		
//		list.forEach(s -> System.out.println(s));   //Lambda 表达式是一种匿名函数
		
		//当获取元素列表时使用?(List<?>),那循环时取出元素可以定义为对象,for (Object e1:list)
		//当获取元素列表时已经明确列表中元素类型(List<Element>),那循环时取出元素可以定义为相应类型(Element),for (Object e1:list)
		for (Element e1:list) {      //当获取元素列表时使用?,那循环时取出元素可以定义为对象,
			// Element E1= (Element)e1;    //只有上面获取元素使用?的方式是,需要强制转换为Element类型
			System.out.println("一级元素"+e1.getName()+":"+e1.getData());          //获取元素标签名
			List<Element> list2 = e1.elements();
			for (Element e2: list2) {				
				//
				//
				/*  
				 * 1、getData() 获取元素的内容(元素文本,及开始标签和结束标签之间的内容,开始标签与结束标签至少有一个换行符)
				 * 2、<chapter id="1">14.发送上传文件的post请求</chapter> 元素文本为 “14.发送上传文件的post请求”加一个换行符
				 * 3、下面projects的getData()获取的是两个换行,一个子标签代表一行(无论子标签下有多少个子孙标签)
				 * <projects> 
				 * 		<project>
				 * 			 <id>1</id> 
				 * 			<name>学生成绩管理</name> 
				 * 		</project> 
				 *      <project>
				 * 			 <id>1</id> 
				 * 			<name>学生成绩管理</name> 
				 * 		</project> 
				 * </projects> 
				 */
				System.out.println("二级元素"+e2.getName()+":"+e2.getData());		
			}
		}
		
	}
 
}

4.3 获取元素属性

package xml;
import java.io.InputStream;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class Testxml_1 {	
  
	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws Exception {
		// 1.加载xml文件到jvm中,形成数据流
		InputStream xml = Testxml_1.class.getClassLoader().getResourceAsStream("demon1.xml");
		
		//2、创建解析对象
		SAXReader sax= new SAXReader();
		
		//3、获取文档对象(整过xml文件)[将数据流转换成一个文档对象]
		Document doc = sax.read(xml);
		
		//4. 获得根元素
		
		Element root = doc.getRootElement();

		//5.获得根元素下的所有子元素
		List<Element>  list = root.elements();
			for(Element e1:list) {
				Attribute miaoshu = e1.attribute("desc"); 
				System.out.println("属性"+e1);		
				System.out.println("属性"+miaoshu.getValue());						
				}
			for(Element e1:list) {
				//
				System.out.println("直接获取属性"+e1.attributeValue("desc"));		
				}
			}
		}

添加元素

package xml;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;



public class Testxml_1 {	
  
	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws Exception {
		// 1.加载xml文件到jvm中,形成数据流
		InputStream xml = Testxml_1.class.getClassLoader().getResourceAsStream("demon1.xml");
		
		//2、创建解析对象
		SAXReader sax= new SAXReader();
		
		//3、获取文档对象(整过xml文件)[将数据流转换成一个文档对象]
		Document doc = sax.read(xml);
		
		//4. 获得根元素		
		Element root = doc.getRootElement();
		System.out.println(root.getName());
		
		//创建元素(节点)是创建到内存中
		Element detail = root.addElement("detail");
		//进一步创建新建节点的子节点
		Element videos=detail.addElement("videos");
		Element video=videos.addElement("video");
		Element chapter1=video.addElement("chapter1");
		chapter1.setText("pthon基础");
		Element chapter2=video.addElement("chapter2");
		chapter2.setText("pthon运算");		
		
		//写入XML文件中
		FileOutputStream out = new FileOutputStream(new File("F:/code.xml"));
		OutputFormat format = new OutputFormat("\t",true,"utf-8");
		XMLWriter XM = new XMLWriter(out,format);
		//将整个文档对象写到文件中
		XM.write(doc);
		System.out.println("写入成功");
		XM.close();
		
			}
		}

xpath

官网地址:https://zvon.org/xxl/XPathTutorial/General_chi/examples.html

  • xpath:是一门在xml文档中快速查找信息的方式
  • 单纯的使用dom4j访问节点时,需要一层一层的查找,
  • 使用xpath访问层级的节点就简单了
  • 使用xpath需要引包:jaxen-1.1-beta-7.jar(jaxen-1.1-beta-6.jar)

dom4j提供基于XPATH的API
Doceument/Element 关于XPath的API
Node selectSingleNode(String xpathExpression); 根据xpath表达式获取单个标签
List selectNodes(String xpathExpression); 根据xpath表达式获取多个标签

xml文件

<?xml version="1.0" encoding="UTF-8"?>
<students>
	<student id="1" type="aa">
		<name>a</name>
		<age>11</age>
	</student>
	<student id="2" >
		<name>b</name>
		<age>22</age>
	</student>
	<student id="3" type="cc">
		<name>c</name>
		<age>33</age>
	</student>
	<beast id="4" >
		<name>d</name>
		<age>44</age>
	</beast>
	<beast id="5" type="ee">
		<name>e</name>
		<age>55</age>
	</beast>
</students>

xpath示例代码

针对跟标签下得一级子标签可以用“/student”也可以直接使用“student”

package xml;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public class Testxml_1 {

	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws Exception {
		// 1.加载xml文件到jvm中,形成数据流
		InputStream xml = Testxml_1.class.getClassLoader().getResourceAsStream("demo5xml.xml");
		// 2、创建解析对象
		SAXReader sax = new SAXReader();
		// 3、获取文档对象(整过xml文件)[将数据流转换成一个文档对象]
		Document doc = sax.read(xml);
		// 4. 获得根元素
		System.out.println("获得根元素");
		Element students = doc.getRootElement();
		System.out.println(students.getName());
		
		System.out.println("");
		System.out.println("使用根目录全文搜索获取name");
		//使用根目录全文搜索获取nam
		List<Element> nameList = students.selectNodes("//name");
		nameList.forEach(s-> System.out.println(s));
		
		System.out.println("");
		System.out.println("使用DOCUMENT对象全文搜索获取name");
		//使用DOCUMENT对象全文搜索获取name
		List<Element> nameList2 = doc.selectNodes("//name");
		nameList2.forEach(s-> System.out.println(s));
		
		System.out.println("");
		System.out.println("获取标签名为student的元素");
		//获取标签名为student的元素
		List<Element> studentList = students.selectNodes("/student");
		studentList.forEach(s-> System.out.println(s));
		System.out.println("获取标签名为beate的元素");
		//获取标签名为beate的元素
		List<Element> beastList = students.selectNodes("beast");
		beastList.forEach(s-> System.out.println(s));
		
		System.out.println("");
		System.out.println("获取所有学生的名字");
		//获取所有学生的名字
		List<Element> namelist= students.selectNodes("student/name");
		namelist.forEach(System.out::println);    //lanmda表达式的另一种形式
		namelist.forEach(s->System.out.println(s.getData()));   //输出标签的文本
		
		System.out.println("");
		System.out.println("获取所有名字,无论层级和位置");
		//获取所有名字,无论层级和位置
		List<Element> namelist2= students.selectNodes("//name");
		namelist2.forEach(System.out::println);    //lanmda表达式的另一种形式

		System.out.println("");
		System.out.println("获得第一个学生的名字");
		//获得第一个学生的名字
		List<Element> firststudent= students.selectNodes("student[1]");
		firststudent.forEach(System.out::println);    //lanmda表达式的另一种形式
		
		System.out.println("");
		System.out.println("获得最后一个学生的名字");
		//获得最后一个学生的名字
		List<Element> laststudent= students.selectNodes("student[last()]");
		laststudent.forEach(System.out::println);    //lanmda表达式的另一种形式
		
		System.out.println("");
		System.out.println("获得倒数第二个学生的名字");
		//获得倒数第二个学生的名字
		List<Element> lastsecondstudent= students.selectNodes("student[last()-1]");
		lastsecondstudent.forEach(s->System.out.println(s.getData()));
		
		System.out.println("");
		System.out.println("获得前两个学生");
		//获得前两个学生
		List<Element> fisestudent= students.selectNodes("student[position()<3]");
		fisestudent.forEach(System.out::println);    //lanmda表达式的另一种形式
		
		System.out.println("");
		System.out.println("获得前两个学生的名字");
		//获得前两个学生的名字
		List<Element> fisename= students.selectNodes("student[position()<3]/name");
		fisename.forEach(s->System.out.println(s.getData()));   //输出标签的文本
		
		System.out.println("");
		System.out.println("获得所有有属性type的学生");
		//获得所有有属性type的学生
		List<Element> type= students.selectNodes("student[@type]/name");
		type.forEach(s->System.out.println(s.getData()));   //输出标签的文本
		
		System.out.println("");
		System.out.println("获得type为cc的学生");
		//获得所有有属性type的学生
		List<Element> type2= students.selectNodes("student[@type='cc']/name");
		type2.forEach(s->System.out.println(s.getData()));   //输出标签的文本
		
		System.out.println("");
		System.out.println("获得年龄超过20岁的学生");
		//获得年龄超过20岁的学生
		List<Element> age= students.selectNodes("student[age>20]/name");
		age.forEach(s->System.out.println(s.getData()));   //输出标签的文本
	}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中读取XML文件有多种方式,其中比较常用的是DOM和SAX两种方式。 DOM方式: 1. 加载XML文件 ```java DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document document = db.parse(new File("xmlfile.xml")); ``` 2. 获取根节点 ```java Element root = document.getDocumentElement(); ``` 3. 获取子节点 ```java NodeList nodeList = root.getChildNodes(); ``` 4. 遍历节点 ```java for (int i=0; i<nodeList.getLength(); i++) { Node node = nodeList.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { Element element = (Element) node; // 获取节点内容 String content = element.getTextContent(); // 获取节点属性 String attribute = element.getAttribute("attributeName"); } } ``` SAX方式: 1. 创建SAX解析器 ```java SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); ``` 2. 实现处理器类 ```java class MyHandler extends DefaultHandler { @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // 处理开始标签 } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // 处理结束标签 } @Override public void characters(char[] ch, int start, int length) throws SAXException { // 处理节点内容 } } ``` 3. 解析XML文件 ```java saxParser.parse(new File("xmlfile.xml"), new MyHandler()); ``` 以上是Java读取XML文件的基本方法,具体使用可以根据需求进行调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值