java xml解析方式(DOM、SAX、JDOM、DOM4J)

时间:2023-03-08 19:03:47
java xml解析方式(DOM、SAX、JDOM、DOM4J)

博客已迁移到CSDN《https://blog.csdn.net/qq_33375499

XML值可扩展标记语言,是用来传输和存储数据的。

XMl的特定:

  1. XMl文档必须包含根元素。该元素是所有其他元素的父元素。XML文档中的元素形成了一颗文档树,树中的每个元素都可存在子元素。
  2. 所有XML元素都必须有关闭标签。
  3. XML标签对大小写敏感,并且所有属性值date都需加引号。

XML元素:

XMl元素是只从包括开始标签到结束标签的部分,元素可包含其他元素、文本或两者都包含,也可拥有属性。

XML解析

基础方法:DOM、SAX

DOM解析:平台无关的官方解析方式

SAX解析:Java中基于事件驱动的解析方式

扩展方法:JDOM、DOM4J (在基础方法上扩展的,只有Java能够使用的解析方式)

1.DOM解析

    优点:

      ·形成了树结构,直观好理解

      ·解析过程中树结构保留在内存中方便修改

    缺点:

      ·当xml文件较大时,对内存消耗比较大,容易影响解析性能,并造成内存溢出

import org.w3c.dom.*;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.util.LinkedList;
import java.util.List; /**
* DOM 解析xml
*/
public class DOM {
public static void main(String[] args) throws Exception {
// 1.创建 DocumentBuilderFactory 对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 2.通过 DocumentBuilderFactory对象创建 DocumentBuilder对象
DocumentBuilder db = dbf.newDocumentBuilder();
// 3.使用 DocumentBuilder对象来加载xml
Document document = db.parse("bean.xml");
System.out.println("----------------- DOM开始解析 xml -----------------");
// 获取 xml 文件的根节点
Element element = document.getDocumentElement();
getNoeMsg(element);
System.out.println("\n\n----------------- DOM结束解析 xml -----------------");
} /**
* 获取Node节点信息
* @param node
*/
public static void getNoeMsg(Node node){
if(node.getNodeType() == Node.ELEMENT_NODE){
System.out.print("<" + node.getNodeName());
getNodeAttrs(node);
System.out.print(">\n");
NodeList nodeList = node.getChildNodes();
// 筛选出节点类型为ELEMENT_NODE 的节点
List<Node> list = getNodeList(nodeList);
Node childNode;
int len = list.size();
if(len == 0){
System.out.print(node.getTextContent() + "\n");
}else {
for (int i = 0; i < len; i++){
if(list.get(i).getNodeType() == Node.ELEMENT_NODE){
childNode = list.get(i);
getNoeMsg(childNode);
}
}
}
System.out.println("</" + node.getNodeName() + ">");
}
} /**
* 获取Node节点的属性信息
* @param node
*/
public static void getNodeAttrs(Node node){
NamedNodeMap attrs = node.getAttributes();
Node attr;
if(attrs.getLength() != 0){
for (int i = 0, len = attrs.getLength(); i < len; i++){
attr = attrs.item(i);
System.out.print(" " + attr.getNodeName() + "='");
System.out.print(attr.getNodeValue() + "'");
}
}
} /**
* 筛选出节点类型为ELEMENT_NODE 的节点
* @param nodeList
* @return
*/
public static List<Node> getNodeList(NodeList nodeList){
List<Node> list = new LinkedList<>();
for (int i = 0,len = nodeList.getLength(); i < len; i++){
if(nodeList.item(i).getNodeType() == Node.ELEMENT_NODE){
list.add(nodeList.item(i));
}
}
return list;
}
}

2.SAX解析

    优点:

      ·采用事件驱动模式,对内存消耗比较小

      ·适用于只需处理xml中数据时

    缺点:

      ·不易编码

      ·很难同时访问同一个xml中的多处不同数据

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; public class SAX {
public static void main(String[] args) throws Exception {
// 1.创建SAXParserFactory对象
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
// 2.通过SAXParserFactory对象创建 SAXParser
SAXParser saxParser = saxParserFactory.newSAXParser();
// 3.通过SAXParser加载xml,并传入 DefaultHandler 类型的对象进行解析
saxParser.parse("bean.xml", new SAXParserHandler());
} static class SAXParserHandler extends DefaultHandler{
/**
* 解析xml开始执行方法
* @throws SAXException
*/
@Override
public void startDocument() throws SAXException {
super.startDocument();
System.out.print("============= SAX开始解析xml =============\n");
} /**
* 解析xml结束执行方法
* @throws SAXException
*/
@Override
public void endDocument() throws SAXException {
super.endDocument();
System.out.print("\n============= SAX结束解析xml =============");
} /**
* 解析节点开始执行方法
* @param uri
* @param localName
* @param qName
* @param attributes
* @throws SAXException
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
System.out.print("<" + qName);
for (int i = 0,len = attributes.getLength(); i < len; i++){
System.out.print(" " + attributes.getQName(i) + "='");
System.out.print(attributes.getValue(i) + "'");
}
System.out.print(">");
} /**
* 解析节点结束执行方法
* @param uri
* @param localName
* @param qName
* @throws SAXException
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
System.out.print("</" + qName + ">");
} @Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
String str = new String(ch, start, length);
System.out.print(str);
}
}
}

3.JDOM解析

    特征:

      ·使用了具体类,不使用接口。

      ·API大量使用了Collections类,源码开源

import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List; /**
* <!-- 引入JDOM依赖包 -->
* <dependency>
* <groupId>org.jdom</groupId>
* <artifactId>jdom</artifactId>
* <version>1.1</version>
* </dependency>
*/
public class JDOM {
public static void main(String[] args) throws IOException, JDOMException {
// 1.创建SAXBuilder对象
SAXBuilder saxBuilder = new SAXBuilder();
// 2.获取xml文件输入流
InputStream in = new FileInputStream("bean.xml");
// 3.通过SAXBuilder对象的build方法,将xml文件输入流添加到SAXBuilder对象中
Document document = saxBuilder.build(in);
// 4.获取xml根节点
Element rootElement = document.getRootElement();
// 5.根据根节点解析xml
printNodeMsg(rootElement);
} public static void printNodeMsg(Element element){
System.out.print("<" + element.getName());
// 获取节点的属性
printAttrmsg(element);
System.out.print(">\n");
List<Element> elements = element.getChildren();
for (Element e : elements){
if(e.getChildren().size() > 0){
printNodeMsg(e);
}else {
System.out.print("<" + e.getName());
printAttrmsg(e);
System.out.print(">");
System.out.print(e.getValue());
System.out.print("</" + e.getName() + ">\n");
}
}
System.out.print("</" + element.getName() + ">\n");
} /**
* 获取节点的属性
* @param element
*/
public static void printAttrmsg(Element element){
List<Attribute> attributes = element.getAttributes();
for (Attribute attribute : attributes){
System.out.print(" " + attribute.getName() + "='" + attribute.getValue() + "'");
}
}
}

4.DOM4J解析

    特征:

    ·使用了接口和抽象基本类方法

    ·具有性能优异、灵活性好、功能强大和极端易用的特点。

    ·开源

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Iterator; /**
* <!-- dom4j依赖包 -->
* <dependency>
* <groupId>dom4j</groupId>
* <artifactId>dom4j</artifactId>
* <version>1.6.1</version>
* </dependency>
*/
public class DOM4J {
public static void main(String[] args) throws FileNotFoundException, DocumentException {
// 1.创建SAXReader对象
SAXReader saxReader = new SAXReader();
// 2.通过SAXReader对象的read方法,加载xml输入流
Document document = saxReader.read(new FileInputStream("bean.xml"));
// 3.通过Document对象获取xml的根节点
Element rootElement = document.getRootElement();
// 4.通过根节点解析xml
printNodeMsg(rootElement);
} public static void printNodeMsg(Element element){
System.out.print("<" + element.getName());
// 获取节点的属性
printAttrmsg(element);
System.out.print(">\n");
Iterator<Element> elementIterator = element.elementIterator();
Element e;
while (elementIterator.hasNext()){
e = elementIterator.next();
if(e.elementIterator().hasNext()){
printNodeMsg(e);
}else {
System.out.print("<" + e.getName());
printAttrmsg(e);
System.out.print(">");
System.out.print(e.getStringValue());
System.out.print("</" + e.getName() + ">\n");
}
}
System.out.print("</" + element.getName() + ">\n");
} /**
* 获取节点的属性
* @param element
*/
public static void printAttrmsg(Element element){
Iterator<Attribute> attributeIterator = element.attributeIterator();
Attribute attribute;
while (attributeIterator.hasNext()){
attribute = attributeIterator.next();
System.out.print(" " + attribute.getName() + "='" + attribute.getValue() + "'");
}
}
}