前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java操作XML文件

Java操作XML文件

作者头像
全栈程序员站长
发布2022-09-08 11:29:17
1.5K0
发布2022-09-08 11:29:17
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

目录

一、使用DOM4j进行XML的DOM解析

1.1、使用DOM4j查询XML文档

1.2、使用DOM4j修改XML文档

1.3、使用xPath技术

二、使用SAX方式解析XML文档

2.1、使用SAX解析方式查询XML文档

2.2、对比DOM解析和SAX解析


Java中有两种解析XML文件的方式:DOM解析和SAX解析。

一、使用DOM4j进行XML的DOM解析

DOM解析是一次性将整个XML文档加载进内存,在内存中构建Document的对象树,通过Document对象,得到树上的节点对象,通过节点对象访问(操作)到XML文档的内容。

通常使用Dom4j工具进行XML的DOM解析,首先要到Dom4j的官网https://dom4j.github.io/下载包并加载到IDE开发工具中(例如eclipse)。

1.1、使用DOM4j查询XML文档

XML文档在DOM解析中可以被映射为多种节点,其中比较重要和常见的是元素节点(Element)、属性节点(Attribute)和文本节点(Text)。

查询节点主要可以使用以下方法:

  • Document new SAXReader().read(File file) —— 读取XML文档
  • Element Document.getRootElement() —— 获取XML文档的根元素节点
  • Iterator Element.nodeIterator() —— 获取当前元素节点下的所有子节点
  • Iterator<Element> Element.elementIterator(元素名) —— 指定名称的所有子元素节点
  • Iterator<Attribute> Element.attributeIterator() —— 获取所有子属性节点
  • List<Element> Element.elements() —— 获取所有子元素节点
  • List<Attribute> Element.attributes() —— 获取所有子属性字节
  • Element Element.element(元素名) —— 指定名称的第一个子元素节点
  • Attribute Element.attribute(属性名) —— 获取指定名称的子属性节点
  • String Element.attributeValue(属性名) —— 获取指定名称的子属性的属性值
  • String Attribute.getName() —— 获取属性名称
  • String Attribute.getValue() —— 获取属性值
  • String Element.getText() —— 获取当前元素节点的子文本节点
  • String Element.elementText(元素名) —— 获取当前元素节点的指定名称的子文本节点

示例:在eclipse中读取以下students.xml文档的内容,并打印至控制台

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>

<Students>
  <Student id="001">
    <name>张三</name>
    <age>19</age>
    <gender>男</gender>
    <grade>计算机1班</grade>
  </Student>
  <Student id="002">
    <name>李四</name>
    <age>20</age>
    <gender>男</gender>
    <grade>计算机2班</grade>
  </Student>
</Students>
代码语言:javascript
复制
package xml;

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

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

public class ReadAndPrintXML {
	public static void main(String[] args) throws Exception {
		// 创建一个XML解析器对象
		SAXReader reader = new SAXReader();
		// 读取XML文档,返回Document对象
		Document document = reader.read(new File("E:\\xml\\students.xml"));
		
		// 获取根元素节点
		Element root = document.getRootElement();
		StringBuilder sb = new StringBuilder();
		recursion(root, sb);
		System.out.println(sb.toString());
	}
	
	private static void recursion(Element ele, StringBuilder sb) {
		sb.append("<");
		// 解析元素节点
		sb.append(ele.getName());
		
		// 解析属性节点
		List<Attribute> attributes = ele.attributes();
		for(Attribute attribute : attributes) {
			sb.append(" ");
			sb.append(attribute.getName());
			sb.append("=");
			sb.append(attribute.getValue());
		}
		
		sb.append(">");
		
		// 解析文本节点
		sb.append(ele.getText());
		
		// 递归解析元素节点
		List<Element> elements = ele.elements();
		for(Element element : elements) {
			recursion(element, sb);
		}
		
		sb.append("<" + ele.getName() + "/>\n");
	}

}

1.2、使用DOM4j修改XML文档

①写出内容到xml文档

XMLWriter writer = new XMLWriter(OutputStream out, OutputFormat format)

writer.write(Document doc)

上面的OutputFormat对象可以由OutputFormat类的两个静态方法来生成:

  • createPrettyPrint() —— 生成的OutputFormat对象,使写出的XML文档整齐排列,适合开发环境使用
  • createCompactFormat() —— 生成的OutputFormat对象,使写出的XML文档紧凑排列,适合生产环境使用

②生成文档或增加节点

  • Document DocumentHelper.createDocument() —— 生成一个新的XML Document对象
  • Element Element.addElement(元素节点名) —— 增加一个子元素节点
  • Attribute Element.addAttribute(属性名,属性值) —— 增加一个子属性节点

③修改节点

  • Attribute.setValue(属性值) —— 修改属性节点值
  • Attribute Element.addAttribute(同名属性名,属性值) —— 修改同名的属性节点值
  • Element.setText(内容) —— 修改文本节点内容

④删除节点

  • Element.detach() —— 删除元素节点
  • Attribute.detach() —— 删除属性节点

示例:生成一个和前面的students.xml一样的XML文档,并写入到磁盘

代码语言:javascript
复制
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;

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

public class WriteXML {
	public static void main(String[] args) throws Exception {
		// 创建一个XMLWriter对象
		OutputFormat format = OutputFormat.createPrettyPrint();
		XMLWriter writer = new XMLWriter(new FileOutputStream("E:\\xml\\students2.xml"), format);
		// 生成一个新的Document对象
		Document doc = DocumentHelper.createDocument();
		// 增加Students元素节点
		Element students = doc.addElement("Students");
		// 增加两个Student元素节点
		Element student1 = students.addElement("student");
		Element student2 = students.addElement("student");
		// 为两个Student元素节点分别增加id属性节点
		student1.addAttribute("id", "001");
		student2.addAttribute("id", "002");
		// 分别增加name, age, gender, grade元素子节点
		student1.addElement("name").setText("张三");
		student1.addElement("age").setText("19");
		student1.addElement("gender").setText("男");
		student1.addElement("grade").setText("计算机1班");
		student2.addElement("name").setText("李四");
		student2.addElement("age").setText("20");
		student2.addElement("gender").setText("男");
		student2.addElement("grade").setText("计算机2班");
		// 将Document对象写入磁盘
		writer.write(doc);
		writer.close();
	}
}

1.3、使用xPath技术

使用dom4j查询比较深的层次结构的节点时,比较麻烦,因此可以使用xPath技术快速获取所需的节点对象。

首先也需要在eclipse中导入xPath的jar包,我这里使用的是jaxen-1.1-beta-6.jar

①使用xPath的方法

  • List<Node> Document.selectNodes(xpath表达式) —— 查询多个节点对象
  • Node Document.selectSingleNode(xpath表达式) —— 查询一个节点对象

②xPath表达式语法

  • / —— 绝对路径,表示从xml文档的根位置开始
  • // —— 相对路径,表示不分任何层次结构的选择元素
  • * —— 表示匹配所有元素
  • [] —— 条件,表示选择符合条件的元素
  • @ —— 属性,表示选择属性节点
  • and —— 关系,表示条件的与关系
  • text() —— 文本,表示选择文本内容

示例:

代码语言:javascript
复制
import java.io.File;
import java.util.List;

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

public class XPathTest {
	public static void main(String[] args) throws Exception {
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new File("E:\\xml\\students.xml"));
		
		// 选择所有的student元素
		List<Node> list = doc.selectNodes("//Student");
		
		// 选择文本内容是"张三"的name元素
		Element name = (Element) doc.selectSingleNode("//name[text()='张三']");
		
		// 选择所有id属性节点
		List<Node> list2 = doc.selectNodes("//@id");
		
		// 选择id属性为002的student元素
		Element student = (Element) doc.selectSingleNode("//Student[@id='002']");
		
		// 选择根元素节点的所有子节点
		Element root = doc.getRootElement();
		List<Node> list3 = doc.selectNodes("/Students/*");
	}
}

二、使用SAX方式解析XML文档

SAX方式解析的原理是:在内存中加载一点,读取一点,处理一点。对内存要求比较低。

JDK内置了SAX解析工具,存放在org.xml.sax包中。

2.1、使用SAX解析方式查询XML文档

核心的API类:

1、SAXParser.parse(File f, DefaultHandler dh)方法:解析XML文件

参数一File:表示读取的XMl文件

参数二DefaultHandler:SAX事件处理程序,包含SAX解析的主要逻辑。开发人员需要写一个DefaultHandler的子类,然后将其对象作为参数传入parse()方法。

2、 SAXParserFactory类,用于创建SAXParser对象,创建方式如下:

SAXParser parse = SAXParserFactory.newInstance().newSAXParser();

3、DefaultHandler类的主要方法:

  • void startDocument() —— 在读到文档开始时调用
  • void endDocument() —— 在读到文档结束时调用
  • void startElement(String uri, String localName, String qName, Attributes attributes) —— 读到开始标签时调用
  • void endElement(String uri, String localName, String qName) —— 读到结束标签时调用
  • characters(char[] ch, int start int length) —— 读到文本内容时调用

示例:使用SAX解析方式读取上面students.xml的内容,并打印至控制台。

代码语言:javascript
复制
import java.io.File;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SAXTest {
	public static void main(String[] args) throws Exception {
		SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
		parser.parse(new File("E:\\xml\\students.xml"), new MyDefaultHandler());
	}
}

class MyDefaultHandler extends DefaultHandler{
	@Override
	public void startDocument() throws SAXException {
		System.out.println("----文档开始解析-------");
	}
	
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		System.out.print("<" + qName);
		
		for(int i = 0; i < attributes.getLength(); i++) {
			System.out.print(" " + attributes.getQName(i) + "=" + attributes.getValue(i));
		}
		System.out.print(">");
	}
	
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		System.out.print(new String(ch, start, length));
	}
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		System.out.print("</" + qName + ">");
	}
	
	@Override
	public void endDocument() throws SAXException {
		System.out.println("\n----文档开始解析结束-----");
	}
}

2.2、对比DOM解析和SAX解析

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/156676.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、使用DOM4j进行XML的DOM解析
    • 1.1、使用DOM4j查询XML文档
      • 1.2、使用DOM4j修改XML文档
        • 1.3、使用xPath技术
        • 二、使用SAX方式解析XML文档
          • 2.1、使用SAX解析方式查询XML文档
            • 2.2、对比DOM解析和SAX解析
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档