目录
一、使用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解析。
DOM解析是一次性将整个XML文档加载进内存,在内存中构建Document的对象树,通过Document对象,得到树上的节点对象,通过节点对象访问(操作)到XML文档的内容。
通常使用Dom4j工具进行XML的DOM解析,首先要到Dom4j的官网https://dom4j.github.io/下载包并加载到IDE开发工具中(例如eclipse)。
XML文档在DOM解析中可以被映射为多种节点,其中比较重要和常见的是元素节点(Element)、属性节点(Attribute)和文本节点(Text)。
查询节点主要可以使用以下方法:
示例:在eclipse中读取以下students.xml文档的内容,并打印至控制台
张三
19
男
计算机1班
李四
20
男
计算机2班
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 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 elements = ele.elements();
for(Element element : elements) {
recursion(element, sb);
}
sb.append("<" + ele.getName() + "/>\n");
}
}
①写出内容到xml文档
XMLWriter writer = new XMLWriter(OutputStream out, OutputFormat format)
writer.write(Document doc)
上面的OutputFormat对象可以由OutputFormat类的两个静态方法来生成:
②生成文档或增加节点
③修改节点
④删除节点
示例:生成一个和前面的students.xml一样的XML文档,并写入到磁盘
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();
}
}
使用dom4j查询比较深的层次结构的节点时,比较麻烦,因此可以使用xPath技术快速获取所需的节点对象。
首先也需要在eclipse中导入xPath的jar包,我这里使用的是jaxen-1.1-beta-6.jar
①使用xPath的方法
②xPath表达式语法
示例:
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 list = doc.selectNodes("//Student");
// 选择文本内容是"张三"的name元素
Element name = (Element) doc.selectSingleNode("//name[text()='张三']");
// 选择所有id属性节点
List list2 = doc.selectNodes("//@id");
// 选择id属性为002的student元素
Element student = (Element) doc.selectSingleNode("//Student[@id='002']");
// 选择根元素节点的所有子节点
Element root = doc.getRootElement();
List list3 = doc.selectNodes("/Students/*");
}
}
SAX方式解析的原理是:在内存中加载一点,读取一点,处理一点。对内存要求比较低。
JDK内置了SAX解析工具,存放在org.xml.sax包中。
核心的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类的主要方法:
示例:使用SAX解析方式读取上面students.xml的内容,并打印至控制台。
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----文档开始解析结束-----");
}
}