【Java EE】Day12 XML、约束(DTD、Schema)、解析方式、Jsoup、选择器(Selector、XPath)
一、XML介绍
1、概述
- Extensible Markup Language--可扩展标记语言
- 标记语言 :标签构成
- 可扩展:可以自定义标签
2、功能
- 存储数据
- 作为配置文件使用
- 作为数据载体在网络中传输
3、与HTML的关系
- w3c(World Wide Web Consortium)万维网发布了HTML和XML技术标准
- 与properties竞争
- 区别:
- XML标签自定义,HTML标签预定义
- XML语法严格,HTML语法松散
- XML用于存储,HTML用于显示
4、语法
- 基本语法:
- 后缀名为xml
- 第一行进行文档声明:<?xml version='1.0' ?>
- 有且只有一个根标签
- 属性值加引号
- 标签必须正确被关闭(自闭和或围堵标签)
- 标签名区分大小写
- 判断:浏览器打开正常显示缩进
<?xml version='1.0' ?> <users> <user id='1'> <name>zhangsan</name> <age>23</age> <gender>male</gender> </user> <user id='2'> <name>lisi</name> <age>18</age> <gender>female</gender> </user> </users>
- 组成
- 文档声明:<?xml 属性列表 ?>
- version:必须包含,1.0
- encoding:默认值:ISO-8859-1【IDEA根据此值修改文件编码】
- standalone:是否独立(不依赖于其他文件)
- 指令(了解):结合css,<?xml-stylesheet type="text/css" href="a.css" ?>
- 标签:自定义标签
- 不能以数字和符号开头
- 不能以xml等字符开头
- 不能包括空格
- 属性
- 文本内容:<![CDATA[ 数据 ]]>被原样展示的数据
- 约束
- 文档声明:<?xml 属性列表 ?>
二、约束
1、概述
- 通过约束,规定xml文档的书写规则
- 需要:在xml中引入约束文档&读懂约束文档
- 约束文档分类
- DTD:简单
- Schema:复杂
2、DTD
- 将dtd文档引入到xml文档中
- 内部dtd:将约束定义在xml中
- 外部dtd:将约束定义在外部dtd文件中
- 本地:<!DOCTYPE 根标签名 SYSTEM "dtd文件的位置">
- 网络:<!DOCTYPE 根标签名 PUBLIC "dtd文件的名字" "dtd文件的URL位置">
<?xml version="1.0" encoding="UTF-8" ?> <!--<!DOCTYPE students SYSTEM "student.dtd">--> <!--内部DTD--> <!DOCTYPE students [ <!ELEMENT students (student*) > <!--*表示0次或多次,+表示一次或多次--> <!ELEMENT student (name,age,sex)> <!ELEMENT name (#PCDATA)> <!ELEMENT age (#PCDATA)> <!ELEMENT sex (#PCDATA)> <!ATTLIST student number ID #REQUIRED> ]> <students> <student number="s001"> <name>张三</name> <age>23</age> <sex>male</sex> </student> <student number="s002"> <name>李四</name> <age>18</age> <sex>female</sex> </student> </students>
外部dtd:
<!ELEMENT students (student*) > <!--*表示0次或多次,+表示一次或多次--> <!ELEMENT student (name,age,sex)> <!ELEMENT name (#PCDATA)> <!ELEMENT age (#PCDATA)> <!ELEMENT sex (#PCDATA)> <!ATTLIST student number ID #REQUIRED>
3、Schema(xsd)
- 原因:DTD不能对内容进行限制
<?xml version="1.0"?> <xsd:schema xmlns="http://www.itcast.cn/xml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.itcast.cn/xml" elementFormDefault="qualified"> <xsd:element name="students" type="studentsType"/> <xsd:complexType name="studentsType"> <xsd:sequence> <xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="studentType"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="age" type="ageType" /> <xsd:element name="sex" type="sexType" /> </xsd:sequence> <xsd:attribute name="number" type="numberType" use="required"/> </xsd:complexType> <xsd:simpleType name="sexType"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="male"/> <xsd:enumeration value="female"/> </xsd:restriction> </xsd:simpleType> <xsd:simpleType name="ageType"> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="0"/> <xsd:maxInclusive value="256"/> </xsd:restriction> </xsd:simpleType> <xsd:simpleType name="numberType"> <xsd:restriction base="xsd:string"> <xsd:pattern value="heima_\d{4}"/> </xsd:restriction> </xsd:simpleType> </xsd:schema>
使用
<?xml version="1.0" encoding="UTF-8" ?> <!-- 1.填写xml文档的根元素 2.引入xsi前缀. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3.引入xsd文件命名空间. xsi:schemaLocation="http://www.itcast.cn/xml student.xsd" 4.为每一个xsd约束声明一个前缀,作为标识 xmlns="http://www.itcast.cn/xml" --> <students xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.itcast.cn/xml student.xsd" xmlns="http://www.itcast.cn/xml" > <!--可以加前缀xmlns:a,适用于多个xsd明明空间起名 xsi:schemaLocation="http://www.itcast.cn/xml student.xsd" xsi:schemaLocation="http://www.itcast.cn/xml1 student1.xsd" --> <student number="heima_0001"> <name>zhangsan</name> <age>23</age> <sex>male</sex> </student> <student number="heima_0002"> <name>lisi</name> <age>18</age> <sex>female</sex> </student> </students>
三、解析
1、概念
- 解析/读取:将文档数据读取到内存
- 写入:内存数据持久化在xml文档中
2、解析方式及思想
- DOM思想
- document object model,用于服务器端
- 将标记语言文档一次性加载到内存,形成一颗DOM树
- 特点:方便CRUD,消耗内存,不适用小内存设备
- SAX思想
- 根据指针逐行读取,设置监听器判断标签,用于移动端
- 特点:不占内存,只能读,不能增删改
3、XML的常见的解析器
- JAXP:SUN公司提供的解析器,支持dom和sax两种思想,性能差,代码麻烦
- DOM4J:一款非常优秀的解析器,基于dom实现
- Jsoup:是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。【也可以用来解析xml】
- PULL:安卓Android内置解析器,sax思想
四、Jsoup
1、快速入门
- 步骤:
- 导包
- 获取document对象
- 获取标签的Element对象
- 获取数据
public static void main(String[] args) throws IOException { //2.获取document对象,根据xml文档获取 //2.1获取student.xml的path,通过类加载器 String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath(); //2.解析xml文档,加载文档进内存,获取dom树--->Documenr Document document = Jsoup.parse(new File(path), "utf-8"); //3.获取元素对象Element标签对象,需求:获取name下的tom值 Elements elements = document.getElementsByTag("name");//当做arraylist System.out.println(elements.size()); //3.1 获取第一个name的Element对象,可以通过索引拿到 Element element = elements.get(0); //3.2 获取数据 String name = element.text(); System.out.println(name); }
2、组成
- Jsoup:工具类,解析html文档或xml文档,返回Document
- Document:文档对象:代表内存中的dom树
- Elements:元素Element对象的集合,可以当做ArrayList<Element>来使用
- Element:元素对象,获取名称属性或文本
- Node:节点对象,是上述对象的父类
- 是Document和Element的父类
3、Jsoup对象
- parse的重载,返回document对象
- 文件
- 链接
- 字符串
package cn.itcast.xml.jsoup; 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; import java.net.URL; /** * Jsoup对象功能 */ public class JsoupDemo2 { public static void main(String[] args) throws IOException { //2.获取document对象,根据xml文档获取 //2.1获取student.xml的path,通过类加载器 String path = JsoupDemo2.class.getClassLoader().getResource("student.xml").getPath(); //2.解析xml文档,加载文档进内存,获取dom树--->Documenr /*Document document = Jsoup.parse(new File(path), "utf-8"); System.out.println(document);*/ //第二种方式static Document parse(String html) 解析字符串 /* String str="<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" + "\n" + "<students>\n" + "\t<student number=\"heima_0001\">\n" + "\t\t<name>zhangsan</name>\n" + "\t\t<age>23</age>\n" + "\t\t<sex>male</sex>\n" + "\t</student>\n" + "\t<student number=\"heima_0002\">\n" + "\t\t<name>lisi</name>\n" + "\t\t<age>18</age>\n" + "\t\t<sex>female</sex>\n" + "\t</student>\n" + " </students>"; Document document = Jsoup.parse(str); System.out.println(document);*/ //第三种方式static Document parse(URL url, int timeoutMillis) 通过网络路径获取指定的html文档或xml文档 //可以进行爬虫 URL url = new URL("https://baike.baidu.com/item/jsoup/9012509?fr=aladdin");//代表网络中的资源路径 Document document = Jsoup.parse(url, 5000); System.out.println(document); } }
4、Document对象
- 代表文档中的dom树
- 用于获取Element对象
- 常用方法
package cn.itcast.xml.jsoup; 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; import java.net.URL; /** * Document/Element对象功能 */ public class JsoupDemo3 { public static void main(String[] args) throws IOException { //1获取student.xml的path,通过类加载器 String path = JsoupDemo3.class.getClassLoader().getResource("student.xml").getPath(); //2.获取Document对象 Document document = Jsoup.parse(new File(path), "utf-8"); //3.获取元素对象 //3.1获取所有student对象 Elements elements = document.getElementsByTag("student"); System.out.println(elements); System.out.println("_________"); //3.2获取属性名为id的元素对象们 Elements elements1 = document.getElementsByAttribute("id"); System.out.println(elements1); System.out.println("_________"); //3.3获取number属性值为heima_0001的元素对象 Elements elements2 = document.getElementsByAttributeValue("number", "heima_0001"); System.out.println(elements2); //3.3获取id属性值的元素对象 Element itcast = document.getElementById("itcast"); System.out.println(itcast); } }
5、Element对象
- 功能
- 获取子元素对象
- 获取属性值
- 获取文本内容
package cn.itcast.xml.jsoup; 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; /** * Element对象功能 */ public class JsoupDemo4 { public static void main(String[] args) throws IOException { //1获取student.xml的path,通过类加载器 String path = JsoupDemo4.class.getClassLoader().getResource("student.xml").getPath(); //2.获取Document对象 Document document = Jsoup.parse(new File(path), "utf-8"); /* 功能 获取子元素对象【子标签】 Elements getElementsByTag(String tagName):根据标签名称获取元素对象集合 Elements getElementsByAttribute(String key):根据属性名称获取元素对象集合 Elements getElementsByAttributeValue(String key, String value):根据对应的属性名和属性值获取元素对象集合 Element getElementById(String id):根据id属性值获取唯一的Element对象 获取属性值 public String attr(String attributeKey):根据属性名称获取属性值 获取文本内容 String text():获取文本内容 String html():获取标签提的所有内容,包括子标签的字符串内容 * */ //通过document对象获取name标签 ,获取所有的name标签 Elements elements = document.getElementsByTag("name"); System.out.println(elements.size()); System.out.println("____________________________"); //通过Element对象获取子标签对象 Element element_student = document.getElementsByTag("student").get(0); Elements ele_name = element_student.getElementsByTag("name"); System.out.println(ele_name.size()); //获取属性,如number的属性值 String number = element_student.attr("NUMBER"); System.out.println(number); //获取name标签的文本内容 String text = ele_name.text(); String html = ele_name.html(); System.out.println(text); System.out.println(html); } }
五、选择器查询
1、常用的选择器
- jsoup提供的快捷查询方式
- selector选择器,使用select方法
- XPath快捷查询语法
2、selector
- 选择器,是Element对象的方法
- 方法:Elements select(String cssQuery)
- 简化css代码书写
package cn.itcast.xml.jsoup; 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; /** * 选择器查询 */ public class JsoupDemo5 { public static void main(String[] args) throws IOException { //1获取student.xml的path,通过类加载器 String path = JsoupDemo5.class.getClassLoader().getResource("student.xml").getPath(); //2.获取Document对象 Document document = Jsoup.parse(new File(path), "utf-8"); //3.查询name标签 /* 之前: div{ } * */ Elements elements = document.select("name"); System.out.println(elements); System.out.println("===================="); //4.查询id值为 itcast的元素 /* 之前: #itcast{ } * */ Elements elements1 = document.select("#itcast"); System.out.println(elements1); System.out.println("===================="); //5.获取student标签且number属性值为heima_0001的age子标签 Elements elements2 = document.select("student[number='heima_0001'] > age"); System.out.println(elements2); } }
3、XPath
- w3c提供的快捷查询语法,可以查询w3cschool的参考手册
- 是XML路径语言,(XML Path Language)
- 用于确定XML中的某部分位置
- 需要额外导包:JsoupXpath-0.3.2
package cn.itcast.xml.jsoup; import cn.wanghaomiao.xpath.exception.XpathSyntaxErrorException; import cn.wanghaomiao.xpath.model.JXDocument; import cn.wanghaomiao.xpath.model.JXNode; 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; import java.util.List; /** * XPath查询 */ public class JsoupDemo6 { public static void main(String[] args) throws IOException, XpathSyntaxErrorException { //1获取student.xml的path,通过类加载器 String path = JsoupDemo6.class.getClassLoader().getResource("student.xml").getPath(); //2.获取Document对象 Document document = Jsoup.parse(new File(path), "utf-8"); //3.根据Document对象,创建JXDocument对象 JXDocument jxDocument = new JXDocument(document); //4.结合xpath语法查询 //4.1查询所有的student标签 List<JXNode> jxNodes = jxDocument.selN("//student"); for (JXNode jxNode : jxNodes) { System.out.println(jxNode); //Element element = jxNode.getElement(); } System.out.println("======================="); //4.2查询所有student标签下的name标签 List<JXNode> jxNodes2 = jxDocument.selN("//student/name"); for (JXNode jxNode : jxNodes2) { System.out.println(jxNode); //Element element = jxNode.getElement(); } System.out.println("======================="); //4.3查询student下带id的name标签 List<JXNode> jxNodes3 = jxDocument.selN("//student/name[@id]"); for (JXNode jxNode : jxNodes3) { System.out.println(jxNode); //Element element = jxNode.getElement(); } System.out.println("======================="); //4.4查询student下带id的name标签,并且id属性值为itcast List<JXNode> jxNodes4 = jxDocument.selN("//student/name[@id='itcast']"); for (JXNode jxNode : jxNodes4) { System.out.println(jxNode); //Element element = jxNode.getElement(); } } }
本文来自博客园,作者:哥们要飞,转载请注明原文链接:https://www.cnblogs.com/liujinhui/p/14881450.html