在Java中有哪些解析XML的方法?

我在模拟tomcat的过程中需要解析xml,所以在此总结下常用的sax/dom,Dom4j,jsoup等。

其实sax/dom使用有点复杂,建议使用DOM4j等技术。
这里sax和dom还有Dom4j借鉴于:https://blog.csdn.net/m0_37499059/article/details/80505567

先看xml

demo.xml

<?xml version="1.0" encoding="utf-8" ?>
<class>
    <student>
        <firstname>cxx1</firstname>
        <lastname>Bob1</lastname>
        <nickname>stars1</nickname>
        <marks>85</marks>
    </student>
    <student rollno="493">
        <firstname>cxx2</firstname>
        <lastname>Bob2</lastname>
        <nickname>stars2</nickname>
        <marks>85</marks>
    </student>
    <student rollno="593" e="ee" class="12er">
        <firstname id="12" class="12er">cxx3</firstname>
        <lastname>Bob3</lastname>
        <nickname>stars3</nickname>
        <marks>85</marks>
    </student>
</class>

SAX

package com.yuer.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;

/**
 * 使用SAX解析xml
 * 优点和缺点:
 * 		SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。
 * 		而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点
 * 		
 * 	
 * 		缺点:不能修改文件,且不支持文件的随意读取
 * 		
 * 
 * @author Yuer
 *
 */
public class SaxDemo {

	public static void main(String[] args) throws Exception {
		// 1.或去SAXParserFactory实例
		SAXParserFactory factory = SAXParserFactory.newInstance();
		// 2.获取SAXparser实例
		SAXParser saxParser = factory.newSAXParser();
		// 创建Handel对象
		SAXDemoHandel handel = new SAXDemoHandel();
		saxParser.parse("src/main/resources/demo.xml", handel);
	}
}

class SAXDemoHandel extends DefaultHandler {
	// 遍历xml文件开始标签
	@Override
	public void startDocument() throws SAXException {
		super.startDocument();
		System.out.println("sax解析开始");
	}

	// 遍历xml文件结束标签
	@Override
	public void endDocument() throws SAXException {
		super.endDocument();
		System.out.println("sax解析结束");
	}

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		super.startElement(uri, localName, qName, attributes);
		if (qName.equals("student")) {
			System.out.println("============开始遍历student=============");
			// System.out.println(attributes.getValue("rollno"));
		} else if (!qName.equals("student") && !qName.equals("class")) {
			System.out.print("节点名称:" + qName + "----");
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		super.endElement(uri, localName, qName);
		if (qName.equals("student")) {
			System.out.println(qName + "遍历结束");
			System.out.println("============结束遍历student=============");
		}
	}

	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		super.characters(ch, start, length);
		String value = new String(ch, start, length).trim();
		if (!value.equals("")) {
			System.out.println(value);
		}
	}
}
运行结果

在这里插入图片描述

DOM

package com.yuer.xml;


import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
/**
 * 使用DOM方式解析xml
 * 优点和缺点:
 * 		核心是按树形结构处理数据,dom解析器读入xml文件并在内存中建立一个结构一模一样的“树”,
 * 		这树各节点和xml各标记对应,通过操纵此“树”来处理xml中的文件。xml文件很大时,建立的“树”也会大,所以会大量占用内存。
 * 		所以优点很容易总结出来:支持随机读取,且能读和写。
 * 		缺点:读取大文件时很耗费内存。
 * @author Yuer
 *
 */
public class DomDemo {
    //用Element方式
    public static void element(NodeList list){
        for (int i = 0; i <list.getLength() ; i++) {
            Element element = (Element) list.item(i);
            NodeList childNodes = element.getChildNodes();
            for (int j = 0; j <childNodes.getLength() ; j++) {
                if (childNodes.item(j).getNodeType()==Node.ELEMENT_NODE) {
                    //获取节点
                    System.out.print(childNodes.item(j).getNodeName() + ":");
                    //获取节点值
                    System.out.println(childNodes.item(j).getFirstChild().getNodeValue());
                }
            }
        }
    }

    public static void node(NodeList list){
        for (int i = 0; i <list.getLength() ; i++) {
            Node node = list.item(i);
            NodeList childNodes = node.getChildNodes();
            for (int j = 0; j <childNodes.getLength() ; j++) {
                if (childNodes.item(j).getNodeType()==Node.ELEMENT_NODE) {
                    System.out.print(childNodes.item(j).getNodeName() + ":");
                    System.out.println(childNodes.item(j).getFirstChild().getNodeValue());
                }
            }
        }
    }

    public static void main(String[] args) {
        //1.创建DocumentBuilderFactory对象
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //2.创建DocumentBuilder对象
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document d = builder.parse("src/main/resources/demo.xml");
            NodeList sList = d.getElementsByTagName("student");
            //element(sList);
            node(sList);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
运行结果

在这里插入图片描述

Dom4j

package com.yuer.xml;

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

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

/**
 * Dom4j方式解析xml
 * 
 * Dom4j是基于底层api的更高级封装。
 * dom4j是目前在xml解析方面是最优秀的(Hibernate、Sun的JAXM也都使用dom4j来解析XML),
 * 它合并了许多超出基本 XML 文档表示的功能,包括集成的 XPath 支持、XML Schema 支持以及用于大文档或流化文档的基于事件的处理
 * @author Yuer
 *
 */
public class Dom4JDemo {
    public static void main(String[] args) throws Exception {
        //1.创建Reader对象
        SAXReader reader = new SAXReader();
        //2.加载xml
        Document document = reader.read(new File("src/main/resources/demo.xml"));
        //3.获取根节点
        Element rootElement = document.getRootElement();
        Iterator iterator = rootElement.elementIterator();
        while (iterator.hasNext()){
            Element stu = (Element) iterator.next();
            List<Attribute> attributes = stu.attributes();
            System.out.println("======获取属性值======");
            for (Attribute attribute : attributes) {
                System.out.println(attribute.getValue());
            }
            System.out.println("======遍历子节点======");
            Iterator iterator1 = stu.elementIterator();
            while (iterator1.hasNext()){
                Element stuChild = (Element) iterator1.next();
                System.out.println("节点名:"+stuChild.getName()+"---节点值:"+stuChild.getStringValue());
            }
        }
    }
}
运行结果

在这里插入图片描述

jsoup

这个主要是用来解析html,相比于其他方式,jsoup简单很多了,也是基于文档树的,里面提供了很多方法用于处理html,xml当然也可以处理,且很容易理解。也可以用于爬虫。

package com.yuer.xml;

import java.io.File;
import java.io.IOException;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/**
 * jsoup主要用来解析HTML,但是也可用于解析xml主要是很简便 也可用于爬虫
 * 
 * @author Yuer
 *
 */
public class TestJsoup {

	/**
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		
		parseXml();
	}

	public static void parseXml() throws IOException {
	// 将xml中的数据弄到StringBuffer中
//		int i = 0;
//		StringBuffer buff = new StringBuffer();
//		FileInputStream fis = new FileInputStream(new File("src/main/resources/demo.xml"));
//
//		while ((i = fis.read()) != -1) {
//			buff.append((char) i);
//		}

		// 获取Document的方式有三种,第一种字符串,第二种文件(先封装为File,还可以指定编码格式如utf-8),第三种网址(需要先封装为URL)
//		Document doc = Jsoup.parse(buff.toString());
		Document doc = Jsoup.parse(new File("src/main/resources/demo.xml"),"utf-8");

//		System.out.println(doc); // 这个会将整个xml打印和直接打印buff的效果一致

		// 获取Elements的方式有很多种:根据id,class,tag,属性(好像是看是否存在这个属性)都可
		Elements as = doc.getElementsByTag("firstname");
		for (Element e : as) {
			// 标签的文本值
			System.out.println(e.text());

		}
		as = doc.getElementsByTag("student");
		for (Element e : as) {
			// 标签的对应属性的值 这里是rollno属性的值
			System.out.println(e.attr("rollno"));

			// 获取该标签的所有值 打印的值类似于这种格式:rollno="593" e="ee"
			System.out.println(e.attributes());

			// 还有一些在html中常用的获取id等等不写了这里主要展示分析xml的方法
			// 还有如jquery的选择器的这里省略,在爬虫那里仔细介绍

		}

		// jsoup和DOM都类似,都采用的建立文档树,可以接受增删改属性,这里好像失效了
		// 这里对元素的修改好像确实修改了,但是没有同步到xml中
		Element e = doc.getElementsByTag("firstname").last();

		System.out.println(doc);
		// 这个可以修改一个Element,也可以直接修改多个如Elements,但是不知道为什么这里失效了
//		e.attr("class", "class1");
		// 增加移除属性 这里好像只支持class
		// 修改文本值 不传值即是获取,传值即是修改
		e.text(" Hello JSoup");
		System.out.println(doc);

//		e.appendText(" Hello JSoup");
	}

	

}

运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
不过这里对于xml的修改好像没成功,不过对于xml生成的Document确实修改了,待解决。。。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值