XML解析的方式
1.DOM解释:将标记语言文档一次性加载到内存中,形参一个dom树
优点:操作方便,可以对文档进行各种增删改查的操作
缺点:占用内存
2.SAX解析:逐行读取,基于事件驱动
优点:不占内存
缺点:只能读取,不能够增删改
常见的XML解析器:
1.JAXP:sun公司的解析器,支持dom和sax思想(但是基本不怎么用)
2.DOM4J:一款非常优秀的解析器,很多框架都使用这个
3.Jsoup:是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据
4.PULL:Android操作系统内置的解析器,SAX方式的
Jsoup详解
1.导入jar包,这个直接网上百度下载就ok了。
2.获取document对象
通过类加载器进行获取xml的路径(前提把其放在和测试类一样的位置)
ClassLoader classLoader = JsoupDemo1.class.getClassLoader();
System.out.println(classLoader);
URL resource = classLoader.getResource("boker/xml/student.xml");
System.out.println(resource);
String path = resource.getPath();
System.out.println("解码前"+path);
String decode = URLDecoder.decode(path, "utf-8");
System.out.println("解码后"+ decode);
/*
jdk.internal.loader.ClassLoaders$AppClassLoader@e73f9ac
file:/G:/Java%e6%96%87%e4%bb%b6/dailyPrograming/out/production/dailyPrograming/boker/xml/student.xml
解码前/G:/Java%e6%96%87%e4%bb%b6/dailyPrograming/out/production/dailyPrograming/boker/xml/student.xml
解码后/G:/Java文件/dailyPrograming/out/production/dailyPrograming/boker/xml/student.xml
*/
笔者在这一步遇到了一个问题,因为我在项目包中起了中文的名字,因此类加载器获取URL资源的时候返回的是URL编码,因此在后面利用File类创建File对象的时候,传入的是没有解码的URL路径,因此导致一直空指针异常。由此,实在不能在Java项目中的文件起中文名,遇到URI会编码,导致难以想象的错误。而且需要注意的是,利用类加载器的getResource方法默认的相对路径是在src目录下的。当然解决这个问题还有一个办法:不使用类加载器,而是直接创建File对象,传入的字符串路径就直接使用相对于项目下的路径就ok了。
package boker.xml;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
/**
* @author 承夕
* @date 2020/2/15 0015 - 19:46
* @contact:https://github.com/chengxi0
*/
public class JsoupDemo1 {
public static void main(String[] args) throws IOException {
//获取document对象
//通过类加载器获取xml文件的路径
//String path = JsoupDemo1.class.getClassLoader().getResource("boker//xml//student.xml").getPath();
//因为笔者的文件路径有中文,因此需要把URI解码
String path= URLDecoder.decode(JsoupDemo1.class.getClassLoader().getResource("boker//xml//student.xml").getPath());
//通过直接创建file对象
File file = new File("src//boker//xml//student.xml");
Document document1 = Jsoup.parse(file, "utf-8");
Document document2 = Jsoup.parse(new File(path), "utf-8");
System.out.println(document1);
System.out.println("-------------------");
System.out.println(document2);
}
}
上述使用的是Jsoup的其中一个静态方法
public static Document parse(File in, String charsetName)throws IOException
还有两个也比较经常用
public static Document parse(String html) 通过HTML或者XML的字符串文档格式创建一个document对象
public static Document parse(URL url, int timeoutMillis) throws IOException 通过网络途径获取指定的html获取xml的文本对象
3.获取对应标签的元素Element对象
Element getElementById(String id) 通过id值获取元素对象(但是这个在xml文档中就很少使用)
Elements getElementsByTag(String tagName) 根据标签名获取元素对象的集合(Elements已经封装成一个数组ArrayList集合类)
Elements getElementsByAttribute(String key) 根据属性名称获取元素对象集合
Elements getElementsByAttributeValue(String key, String value) 根据属性名和属性值获取元素对象集合
package boker.xml;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.File;
import java.io.IOException;
/**
* @author 承夕
* @date 2020/2/15 0015 - 19:46
* @contact:https://github.com/chengxi0
*/
public class JsoupDemo2 {
public static void main(String[] args) throws IOException {
//获取document对象
//通过直接创建file对象
File file = new File("src//boker//xml//student.xml");
Document document = Jsoup.parse(file, "utf-8");
//获取Element对象
//Elements getElementsByTag(String tagName) 根据标签名获取元素对象的集合(Elements已经封装成一个数组ArrayList集合类)
Elements elements1 = document.getElementsByTag("name");
System.out.println(elements1);
System.out.println("--------------");
//Elements getElementsByAttribute(String key) 根据属性名称获取元素对象集合
Elements elements2 = document.getElementsByAttribute("number");
System.out.println(elements2);
System.out.println("-----------------");
//Elements getElementsByAttributeValue(String key, String value) 根据属性名和属性值获取元素对象集合
Elements elements3 = document.getElementsByAttributeValue("number", "s2");
System.out.println(elements3);
System.out.println("---------------------");
//Element getElementById(String id) 通过id值获取元素对象(但是这个在xml文档中就很少使用)
Element elementById = document.getElementById("1");
System.out.println(elementById);
System.out.println("----------------------");
}
}
4.获取数据
获取属性值
public String attr(String attributeKey) 根据属性名称获取属性值(键不区分大小写)
获取文本内容
public String text() 获取文本内容(将本标签的文本及子标签的文本都打印出来)
public String html() 获取标签体的所有内容(包括子标签的字符串内容)
package boker.xml;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.File;
import java.io.IOException;
/**
* @author 承夕
* @date 2020/2/15 0015 - 19:46
* @contact:https://github.com/chengxi0
*/
public class JsoupDemo3 {
public static void main(String[] args) throws IOException {
//获取document对象
//通过直接创建file对象
File file = new File("src//boker//xml//student.xml");
Document document = Jsoup.parse(file, "utf-8");
//获取Element对象
Elements e = document.getElementsByAttributeValue("number", "s2");
//public String attr(String attributeKey) 根据属性名称获取属性值
String s1 = e.attr("number");
System.out.println(s1);
System.out.println("---------------");
//public String text() 获取文本内容 将本标签的文本及子标签的文本都打印出来
String text = e.text();
System.out.println(text);
System.out.println("------------------");
String html = e.html();
System.out.println(html);
System.out.println("--------------------");
}
}
XML查询:
selector:选择器查询
方法:利用document对象的select方法,并查看selector类进行查询
public Elements select(String cssQuery)
package boker.xml;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import java.io.File;
import java.io.IOException;
/**
* @author 承夕
* @date 2020/2/15 0015 - 19:46
* @contact:https://github.com/chengxi0
*/
public class JsoupDemo4 {
public static void main(String[] args) throws IOException {
//获取document对象
//通过直接创建file对象
File file = new File("src//boker//xml//student.xml");
Document document = Jsoup.parse(file, "utf-8");
//查询student标签中number属性为s1的age标签
Elements e = document.select("student[number='s1'] > age");
System.out.println(e);
}
}