XML------parse解析
概念
- XML解析分为:SAX解析和dom解析
- dom和SAX都是一种模型/标准/理论,是需要其他人使用具体的代码去实现的
- 区别:SAX对内存要求低 dom对内存要求高
SAX解析
- SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会文档进行操作。SAX解析器在发现xml文档中的内容时就会调用你重写之后的方法. 如何处理这些内容,由程序员自己决定。
- 对xml文档边读边解析(不需要将整个文档都加载到内存)
- 对xml文档一次性顺序读取,不能随机读取
- 读到后面就忘了前面的内容,要想再次获取前面内容,必须重新读取
- 对xml文档内容是只读的
- 在基于sax 的程序中,有五个最常用sax事件,注意:继承DefaultHandler类,重写以下方法即可。
- startDocument() —> 解析器发现了文档的开始标签 document文件
- endDocument() —> 解析器发现了文档结束标签
- startElement() —> 解析器发现了一个起始标签 element 元素
- character() —> 解析器发现了标签里面的文本值
- endElement() —> 解析器发现了一个结束标签
- SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器。
-
解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。
解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。 -
事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。
sax.xml文件:<?xml version="1.0" encoding="UTF-8"?> <root att="test"> <start>123</start> <end>tom</end> </root>
package com.briup.day02;
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 SAXParse {
public void prase(String file) throws Exception {
//获取sax解析器的工厂类的实例
SAXParserFactory factory = SAXParserFactory.newInstance();
//通过工厂去创建sax解析器
SAXParser saxParser = factory.newSAXParser();
//开始解析xml
saxParser.parse(file,new DefaultHandler(){
//文档解析方法
@Override
public void startDocument() throws SAXException {
System.out.println("解析开始");
super.startDocument();
}
@Override
public void endDocument() throws SAXException {
System.out.println("解析结束");
super.endDocument();
}
//遇到开始标签调用的方法
//uri 命名空间对应的uri
//localName 没有命名空间会为空的没有前缀名的标签名
//qName 标签的全名
//attributes 当前标签上的属性合集
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
System.out.println("解析到"+qName+"标签");
//判断标签是否有属性
if(attributes.getLength()>0) {
for (int i = 0; i < attributes.getLength(); i++) {
//返回每个属性的属性名和属性值
System.out.println("该标签有属性:"+attributes.getQName(i)+" "+attributes.getValue(i));
}
}
super.startElement(uri, localName, qName, attributes);
}
//遇到开始标签调用的方法
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println("标签"+qName+"结束");
super.endElement(uri, localName, qName);
}
//遇到文本会调用的方法
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
System.out.println("遇到文本了"+new String(ch,start,length));
super.characters(ch, start, length);
}
});
}
public static void main(String[] args) {
SAXParse saxParser = new SAXParse();
try {
saxParser.prase("F:\\eclipse 1\\xml\\src\\com\\briup\\day02\\sax.xml");
} catch (Exception e) {
e.printStackTrace();
}
}
}
dom解析
-
在使用 DOM 解析 XML 文档时,需要读取整个 XML 文档,在内存中构建代表整个 DOM 树的Doucment对象,从而再对XML文档进行操作。此种情况下,如果 XML 文档特别大,就会消耗计算机的大量内存,严重情况下可能还会导致内存溢出。
sax.xml文件:<?xml version="1.0" encoding="UTF-8"?> <root att="test"> <start>123</start> <end>tom</end> </root>
package com.briup.day02;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class DomParse {
public void parse(String file) throws Exception {
//获取dom解析器的工厂实例
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//获取dom解析器
DocumentBuilder builder = factory.newDocumentBuilder();
//开始解析xml文件
Document document = builder.parse(file);
//获取根元素
Element root = document.getDocumentElement();
//测试根元素获取是否成功
// String nodeName = root.getNodeName();
// System.out.println(nodeName);
//测试根元素全部子节点
NodeList childNodes = root.getChildNodes();
// System.out.println(childNodes.getLength());
//获取根元素的属性节点(通过属性名)
Attr attr = root.getAttributeNode("att");
//打印属性的值和属性名
System.out.println(attr.getName()+" "+attr.getValue());
//通过for循环遍历root的子节点
for (int i = 0; i < childNodes.getLength(); i++) {
//判断子节点的节点类型为元素节点
Node node = childNodes.item(i);
if(node.getNodeType()==Node.ELEMENT_NODE) {
//得到元素节点的节点名和对应文本值
System.out.println(node.getNodeName()+" "+node.getTextContent());
}
}
}
public static void main(String[] args) {
DomParse parse = new DomParse();
try {
parse.parse("F:\\eclipse 1\\xml\\src\\com\\briup\\day02\\sax.xml");
} catch (Exception e) {
e.printStackTrace();
}
}
}
students.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student id="1001"> <!-- student节点:元素(id)、 属性(name,age,grade)、 文本(换行) -->
<name>tom</name>
<age>19</age>
<grade>80</grade>
</student>
<student id="1002">
<name>lily</name>
<age>19</age>
<grade>90</grade>
</student>
<student id="1003">
<name>jack</name>
<age>19</age>
<grade>85</grade>
</student>
<student id="1004">
<name>Vijay</name>
<age>23</age>
<grade>100</grade>
</student>
</students>
package com.briup.day02;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class DomParseStudent {
public List<Student> parse(String file) throws Exception{
List<Student> list = new ArrayList<>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder dom = factory.newDocumentBuilder();
Document document = dom.parse(file);
Element root = document.getDocumentElement();
//
NodeList studentNodeList = root.getElementsByTagName("student");
//通过for循环获取一个student的全部信息
for (int i = 0; i < studentNodeList.getLength(); i++) {
Student student = new Student();
//获取每一个student节点
Node node = studentNodeList.item(i);
//获取student节点的全部属性
NamedNodeMap attributes = node.getAttributes();
for (int j = 0; j < attributes.getLength(); j++) {
//判断属性名是不是id
if("id".equals(attributes.item(j).getNodeName())) {
String idValue = attributes.item(j).getNodeValue();
student.setId(Integer.parseInt(idValue));
}
}
//获取student节点的全部子节点
NodeList studentchildNodes = node.getChildNodes();
for (int k = 0; k < studentchildNodes.getLength(); k++) {
//子节点的实例
Node studentchildNode = studentchildNodes.item(k);
if ("name".equals(studentchildNode.getNodeName())) {
student.setName(studentchildNode.getTextContent());
}else if ("grade".equals(studentchildNode.getNodeName())) {
student.setGrade(Integer.parseInt(studentchildNode.getTextContent()));
}
}
list.add(student);
}
return list;
}
public static void main(String[] args) {
DomParseStudent student = new DomParseStudent();
try {
int num = 0;
List<Student> list = student.parse("F:\\eclipse 1\\xml\\src\\com\\briup\\day02\\Students.xml");
for (Student student2 : list) {
num+=student2.getGrade();
}
System.out.println("平均成绩:"+(num/list.size()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Student{
private int id;
private String name;
private int age;
private int grade;
public Student(int id, String name, int age, int grade) {
super();
this.id = id;
this.name = name;
this.age = age;
this.grade = grade;
}
public Student() {
super();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + ", grade=" + grade + "]";
}
}
- 创建或更新document对象后,还可以将document对象转换为xml文件
package com.briup.day02;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class DomCreate {
public void create() throws Exception {
//获取dom解析器的工厂实例
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//获取dom解析器
DocumentBuilder dom = factory.newDocumentBuilder();
//通过解析器创建document对象
Document document = dom.newDocument();
//先创建节点
Element address = document.createElement("address");
Element street = document.createElement("street");
Element zip = document.createElement("zip");
//给叶子节点赋值文本
street.setTextContent("学院路");
zip.setTextContent("888号浦东软件园");
//将节点关联到document
document.appendChild(address);
//为address关联子节点
address.appendChild(street);
address.appendChild(zip);
//获取转换文件的工厂类的实例
TransformerFactory factory2 = TransformerFactory.newInstance();
//获取文件转换的实例
Transformer ts = factory2.newTransformer();
//设置编码
ts.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
// ts.setOutputProperty("encoding", "UTF-8");//二选一
//转换文件,储存在项目目录下
ts.transform(new DOMSource(document), new StreamResult(new File("address.xml")));
}
public static void main(String[] args) {
DomCreate create = new DomCreate();
try {
create.create();
} catch (Exception e) {
e.printStackTrace();
}
}
}
dom4j解析
dom4j网址:link
- Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。
- Dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXP也用了Dom4j。
- DOM4j中,获得Document对象的方式有三种:
- 读取XML文件,获得document对象
SAXReader reader = new SAXReader();
Document document = reader.read(new File(“src/input.xml")); - 解析XML形式的文本,得到document对象.
String text = “”;
Document document = DocumentHelper.parseText(text); - 主动创建document对象.
Document document = DocumentHelper.createDocument();
//创建根节点
Element root = document.addElement(“members”);
package com.briup.day02;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class Dom4jParse {
public void parse(String file) throws Exception {
//获取Saxreader对象
SAXReader reader = new SAXReader();
//读取文件获得document对象
Document document = reader.read(file);
//获取根元素
Element root = document.getRootElement();
//根元素获取子元素
List<Element> list = root.elements();
//foreach循环遍历
for (Element element : list) {
//获取student的id属性的值
String id = element.attributeValue("id");
//获取student的name元素和grade元素
String name = element.element("name").getText();
String grade = element.element("grade").getText();
System.out.println("id:"+id+",name:"+name+",grade:"+grade);
}
}
public static void main(String[] args) {
Dom4jParse dom4jParse = new Dom4jParse();
try {
dom4jParse.parse("F:\\eclipse 1\\xml\\src\\com\\briup\\day02\\Students.xml");
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 创建或更新document对象后,还可以将document对象写到xml文件中
package com.briup.day02;
import java.io.FileWriter;
import java.io.IOException;
import org.dom4j.Document;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class Dom4jCrate {
public void crate() throws IOException {
//获取到SAXReader对象
SAXReader saxreader = new SAXReader();
//通过saxreader获取documentFactory工厂
DocumentFactory documentFactory = saxreader.getDocumentFactory();
//创建document对象
Document document = documentFactory.createDocument();
//创建元素
Element root = document.addElement("root");
Element student = root.addElement("student");
Element name = student.addElement("name");
Element age = student.addElement("age");
//添加属性和属性值
student.addAttribute("id", "1001");
//给元素添加文本
name.addText("tom");
age.addText("10");
//将document对象写到xml文件中
FileWriter writer = new FileWriter("src/mytwo.xml");
document.write(writer);
writer.flush();
}
public static void main(String[] args) {
Dom4jCrate create = new Dom4jCrate();
try {
create.crate();
} catch (IOException e) {
e.printStackTrace();
}
}
}