名词解释:
区别 | HTML | XML |
---|---|---|
功能 | 制作网页,主要用于表示层 | 用于配置文件,传递数据 |
大小写 | 不区分大小写 或
|
区分大小写, 或 是不同的 |
语法严谨 | 不严谨,如果一个标签有开头,没有结尾。 浏览器也可以解析。 |
严谨,标签开头和结尾必须严格配对 |
可扩展性 | 没有可扩展性,所有的标签都是固定好, 每个标签的功能固定。 |
所有的标签都是人为创造的,可以扩展。 |
声明:
格式: 以开头,以
?>
结尾
位置:必须出现在XML 文件的第1 行
<
开头,>
结尾, 中间是标签名;特殊字符需要转义才能显示,常用的有
特殊字符 | 转义字符 |
---|---|
< | < |
> | > |
“ | " |
‘ | ' |
& | & |
空格 | |
字符区的内容xml 文件的解释器在解释的时候,全部的内容都会当成普通的文本处理,即使遇到了特殊的符号也会只当成普通的文本去处理。
格式:
处理指令,简称PI(Processing instruction)用来指挥解析引擎如何解析XML 文档内容。
格式: 开头,
?>
结尾
eg:`
xml约束文件分类:
一般不需要编写约束,直接引入已编写完
导入DTD文件方式 | 描述 |
---|---|
|
系统的DTD 文件,使用范围比较小,一般用于公司,不对外开放的DTD 文件 |
|
公共的DTD 文件,用于互联网上,使用广泛的用途 |
|
xml 文件与dtd 文件混合在一起。 |
基本写法如下
<!ELEMENT 书架 (书+)>
<!ELEMENT 书 (书名,作者,售价)>
<!ELEMENT 书名 (#PCDATA)>
<!ELEMENT 作者 (#PCDATA)>
<!ELEMENT 售价 (#PCDATA)>
<书架>
<书>
<书名>哈利波特书名>
<作者>JK罗琳作者>
<售价>49.9售价>
书>
书架>
]>
<书架>
<书>
<书名>哈利波特书名>
<作者>JK罗琳作者>
<售价>49.9售价>
书>
书架>
xml不能判断较多的数据类型,功能比较简单
而Schema功能更加强大,数据类型约束更完善,可取代DTD
新建schema 约束文件(固定格式)
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="名称空间"
elementFormDefault="qualified">
<xs:element name='根元素' >
<xs:complexType>
<xs:sequence maxOccurs='unbounded' >
<xs:element name='子元素' >
<xs:complexType>
<xs:sequence>
<xs:element name='子元素下的子元素1' type='xs:string' />
<xs:element name='子元素下的子元素2' type='xs:string' />
xs:sequence>
xs:complexType>
xs:element>
xs:sequence>
xs:complexType>
xs:element>
xs:schema>
使用schema文件创建xml文件:
<根元素 xmlns="名称空间" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="名称空间 xsd约束文件名">
根元素>
xsd文件:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.baidu.com" --名称空间-->
elementFormDefault="qualified">
<xs:element name='书架' >
<xs:complexType>
<xs:sequence maxOccurs='unbounded' >
<xs:element name='书' >
<xs:complexType>
<xs:sequence>
<xs:element name='书名' type='xs:string' />
<xs:element name='作者' type='xs:string' />
<xs:element name='售价' type='xs:double' />
xs:sequence>
xs:complexType>
xs:element>
xs:sequence>
xs:complexType>
xs:element>
xs:schema>
xml文件:
<书架 xmlns="http://www.baidu.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.baidu.com books.xsd">
<书>
<书名>哈利波特书名>
<作者>JK罗琳作者>
<售价>49.9售价>
书>
书架>
JAXP:Oracle公司提供支持DOM和SAX开发包
Dom4j:比较简单的的解析开发包,将整个XML加载到内存中做为一棵DOM树。
JDom:与Dom4j类似
Jsoup:功能强大DOM方式的XML解析开发包,同时对HTML解析也很方便。
由于所有节点都封装到Document对象中,只要获得Document对象,就可以获取xml的所有节点
- static Document parse(String html);
->将该html内容转换为一个document对象。
->参数String html是整个html文件的内容
☞如果html内容太多,使用该方式将非常不方便,一般很少使用
- static Document parse(File file,"码表");
根据本地的资源文件生成document对象
getResource()
方法获得类路径,类路径必须以/开头(可理解为当前src目录);getPath()
方法获得类路径对应字符串,并据此创建File对象;- URL getResource("/xml文件名");
根据文件名路径获得文件资源URL对象;
- String getPath();
获得URL对象的真实路径
public class Demo02 {
public static void main(String[] args) throws IOException {
//获得类路径
String path = Demo02.class.getResource("/person.xml").getPath();
//创建File对象
File file = new File(path);
//生成document对象。
Document document = Jsoup.parse(file, "UTF-8");
System.out.println(document);
}
}
- static org.jsoup.Connection connect(String url);
通过URL字符串创建连接对象
- Document get(); 通过连接对象返回一个Document对象
public class Demo03 {
public static void main(String[] args) throws IOException {
//根据指定url获得Connection对象
Connection connection = Jsoup.connect("http://baidu.com");
//根据连接对象获得Document对象
Document document = connection.get();
System.out.println(document);
}
}
返回类型 | Document对象的方法 | 说明 |
---|---|---|
Element | getElementById(String id) | 通过id得到唯一元素对象 |
Element*s* | getElementsByTag(String tagName) | 通过标签名得到一组元素 |
Element*s* | getElementsByClass(String className) | 通过类名得到一组元素对象 |
public class Demo01 {
public static void main(String[] args) throws IOException {
//获得Document对象
Document document = Jsoup.parse(new File(Demo01.class.getResource("/index.html").getPath()),"utf-8" );
//1.获取index.html中元素属性id="header"的一个元素并打印输出
Element element = document.getElementById("header");
System.out.println(element);
System.out.println("---------");
//2.获取index.html中所有h2标签名称的元素列表并打印输出
Elements elements = document.getElementsByTag("h2");
elements.forEach(System.out::print);
System.out.println("---------");
//3.获取index.html中所有元素含有class属性值为fl并打印输出
elements = document.getElementsByClass("fl");
elements.forEach(System.out::print);
}
}
返回类型 | 方法 | 说明 |
---|---|---|
Elements | select(String cssQuery) | 作用:通过选择器得到多个元素 |
Element | selectFirst(String cssQuery) | 作用:通过选择器得到第一个元素 |
其中,String cssQuery
指css选择器:
选择器类型 | 选择器语法 |
---|---|
ID选择器 | #id |
class选择器 | .类名 |
标签选择器 | 标签名 |
属性选择器(属性名) | [属性名] |
属性选择器(属性值) | [属性名=属性值] |
public class Demo02 {
public static void main(String[] args) throws IOException {
//获得Document对象
Document document = Jsoup.parse(new File(Demo02.class.getResource("/index.html").getPath()), "utf-8");
//1.获取id="footer"元素并输出元素名称
Elements elements = document.select("#footer");
print(elements);
System.out.println("---------");
//2.获取index.html中所有元素含有class属性值为item并打印输出元素体内容
elements = document.select(".item");
print(elements);
System.out.println("---------");
//3.获取index.html中所有h3标签名称的元素列表并打印输出元素名称
elements = document.select(".item");
print(elements);
System.out.println("---------");
//4.获取index.html中含有属性data-toggle所有元素并打印输出元素名称和元素体数据
elements = document.select("[data-toggle]");
print(elements);
System.out.println("---------");
//5.获取index.html中属性role值为"tablist"的所有元素列表并打印输出元素名称
elements = document.select("[role=tablist]");
print(elements);
}
private static void print(Elements elements) {
elements.forEach(System.out::print);
}
}
选择器代码 | 说明 |
---|---|
标签名.类名 | 交集选择器,同时指定标签名和类名的选择器 |
标签名[属性名] | 得到某标签,包含指定属性的标签。 |
父元素 子元素 | 层级选择器,找某个元素下的所有子元素,选择器之间使用空格隔开 |
兄弟A+兄弟B | 查找在A元素后面第一个同级元素B |
public class Demo03 {
public static void main(String[] args) throws IOException {
//获得Document对象
Document document = Jsoup.parse(new File(Demo03.class.getResource("/index.html").getPath()), "utf-8");
//1.获取index.html中div元素类名为item的元素,并打印元素数据
Elements elements = document.select("div.item");
elements.forEach(System.out::print);
System.out.println();
System.out.println("==============================");
//2.获取index.html中a元素含有属性data-toggle的所有元素列表并打印元素数据
elements = document.select("a[data-toggle]");
elements.forEach(System.out::print);
System.out.println();
System.out.println("==============================");
//3.获取index.html中属性id值为"banner"的所有div子元素并打印元素数据
elements = document.select("#banner div");
elements.forEach(System.out::print);
System.out.println();
System.out.println("==============================");
//4.获取index.html中class="navitem"元素后面同级第一个兄弟section元素并打印元素数据
elements = document.select(".navitem+section");
elements.forEach(System.out::print);
}
}
Element对象的方法 | 说明 |
---|---|
String attr(“属性名”) | 得到元素指定属性的值 |
Elements children() | 得到当前元素所有的子元素,返回集合 |
String tagName() | 得到元素的标签名字 |
String text() | 得到元素主体内容中的文本 |
需求:已有xml保存书的信息,已有一个对应的类Book(String category, String title, String author, int year, double price),使用DOM解析xml,封装成List,并且输出封装好的集合
准备xml文件:
<bookstore>
<book category="CHILDREN">
<title>Harry Pottertitle>
<author>J K. Rowlingauthor>
<year>2005year>
<price>29.99price>
book>
<book category="WEB">
<title>Learning XMLtitle>
<author>Erik T. Rayauthor>
<year>2003year>
<price>39.95price>
book>
bookstore>
Book类代码省略
main代码如下:
public class Demo03 {
public static void main(String[] args) throws IOException {
//获得Document对象
Document document = Jsoup.parse(new File(Demo03.class.getResource("/books.xml").getPath()), "utf-8");
//使用dom解析
Elements books = document.select("book");
//创建List存放book对象
List bookList = new ArrayList<>();
//遍历books获得每个元素
for (Element element : books) {
//创建对象
Book book = new Book();
//获得属性值
String category = element.attr("category");
book.setCategory(category);
//获得element的所有子元素
Elements children = element.children();
//遍历children
for (Element child : children) {
//获得每个子元素的tagName和text,然后进行判断赋值
String tagName = child.tagName();
String text = child.text();
if ("title".equalsIgnoreCase(tagName)) {
book.setTitle(text);
} else if ("author".equalsIgnoreCase(tagName)) {
book.setAuthor(text);
} else if ("year".equalsIgnoreCase(tagName)) {
book.setYear(Integer.parseInt(text));
} else if ("price".equalsIgnoreCase(tagName)) {
book.setPrice(Double.parseDouble(text));
}
}
//每循环一次就给bookList添加元素
bookList.add(book);
}
//输出bookList
for (Book book : bookList) {
System.out.println(book);
}
}
}
导包—>写xPath表达式
1)绝对路径
2)相对路径
3)全文搜索
4)条件筛选
方法 | 说明 |
---|---|
public JXDocument(Document doc) | 通过构造方法创建JXDocument对象 参数:org.jsoup.nodes.Document对象 |
List selN(String xpath) | 通过xpath表达式得到指定的节点对象JXNode 返回一个节点集合 |
JXNode selNOne(String xpath) | 通过xpath表达式得到符合条件的节点对象,返回一个节点 节点:包含属性Attribute或元素Element |
selN()相当于css选择器获得元素的select(),selNOne相当于css选择器获得元素的selectFirst()
方法 | 说明 |
---|---|
Element getElement() | 通过节点得到它的元素 |
List sel(String xpath) | 用在相对路径上,从当前节点开始向下查询其它的子节点 |
/
开头,/
代表了根标签;public class Demo01 {
public static void main(String[] args) throws XpathSyntaxErrorException, IOException {
Document document = Jsoup.parse(new File(Demo01.class.getResource("/index.html").getPath()),"utf-8" );
//使用Document对象获得对应的额JXDocument对象
JXDocument jxDocument = new JXDocument(document);
//需求1: 采用绝对路径获取从根节点开始逐层的/body/div/ul/li节点列表并打印信息
List jxNodes = jxDocument.selN("/body/div/ul/li");
for (JXNode jxNode : jxNodes) {
System.out.println(jxNode);
}
//需求2: 找到head里面link标签
jxNodes = jxDocument.selN("/head/link");
for (JXNode jxNode : jxNodes) {
System.out.println(jxNode);
}
}
}
格式 | 说明 |
---|---|
子元素/孙元素 | 相对当前路径元素里面的子元素的选取 |
./子元素/孙元素 | 功能与上面的写法一样 . 表示当前路径 |
/子元素/孙元素 | 相对当前节点元素位置继续查找节点,需要使用JXNode.sel(xpath)的方法执行相对路径表达式。 |
其实上面三种是等价的,最常用的是第一种
/
不可省略!!.
以及/
sel()
public class Demo02 {
public static void main(String[] args) throws XpathSyntaxErrorException, IOException {
//需求:先采用绝对路径获取body节点,再采用相对路径获取下一级div节点列表并打印信息
//获得JXDocument对象
JXDocument jxDocument = new JXDocument(Jsoup.parse(new File(
Demo02.class.getResource("/index.html").getPath()), "utf-8"));
//使用绝对路径获得当前的元素(body)
JXNode body = jxDocument.selNOne("/body"); //中间的“/”不可省略
//根据相对路径获得下一级的div节点
List jxNodes = body.sel("div");
for (JXNode jxNode : jxNodes) {
System.out.println(jxNode);
}
}
}
获取类型 | 语法代码 |
---|---|
获取元素节点 | 元素名 |
获取属性节点 | @属性名 |
格式 | 说明 |
---|---|
//子元素//元素或@属性(基本格式) | “//”符号,不用逐级写路径,可以直接选取到对应的节点,全文搜索匹配不需要按照逐层级写。 |
例子:
示例 | 含义 |
---|---|
//li | 全文搜索所有的li元素列表,不论li在哪一级元素 |
//div/a/img | 全文搜索所有的div,再逐层级搜索下面的a标签下的img元素 |
//link/@href | 全文搜索link元素,得到它的href属性,属性名前加@符号(注意在@前不要漏了/ !) |
public class Demo03 {
public static void main(String[] args) throws XpathSyntaxErrorException, IOException {
Document document = Jsoup.parse(new File(Demo03.class.getResource("/index.html").getPath()),"utf-8" );
//使用Document对象获得对应的额JXDocument对象
JXDocument jxDocument = new JXDocument(document);
//需求1: 直接全文搜索所有的 li 元素列表并打印
List jxNodes = jxDocument.selN("//li");
for (JXNode jxNode : jxNodes) {
System.out.println(jxNode);
}
//需求2: 直接全文搜索所有的 div,再逐层级搜索下面的 a 元素下的 img 元素列表并打印
jxNodes = jxDocument.selN("//div/a/img");
for (JXNode jxNode : jxNodes) {
System.out.println(jxNode);
}
//需求3: 接获取 link 元素里面 href 属性的值,注意属性要用@符号
jxNodes = jxDocument.selN("//link/@href");
for (JXNode jxNode : jxNodes) {
System.out.println(jxNode);
}
}
}
格式 | 说明 |
---|---|
//元素[@属性=value] | 获取元素属性=value的元素 |
//元素[@属性>value]/@属性 | 获取元素属性>value的元素的所有属性的值 |
//元素[@属性=value]/text() | 获取符合条件元素的纯文本数据 |
//元素[@属性=value]/html() | 获取符合条件元素的html数据(包括标签) |
public class Demo04 {
public static void main(String[] args) throws XpathSyntaxErrorException, IOException {
Document document = Jsoup.parse(new File(Demo04.class.getResource("/index.html").getPath()),"utf-8" );
//使用Document对象获得对应的额JXDocument对象
JXDocument jxDocument = new JXDocument(document);
//需求1: 搜索li,属性为class="nav-active"的元素并打印
List jxNodes = jxDocument.selN("//li[@class='nav-active']");
for (JXNode jxNode : jxNodes) {
System.out.println(jxNode);
}
//需求2: 属性为data-slide-to大于0的元素,再查询data-slide-to的属性值
jxNodes = jxDocument.selN("//li[@data-slide-to>0]/@data-slide-to");
for (JXNode jxNode : jxNodes) {
System.out.println(jxNode);
}
//需求3: 搜索a标签,属性为href="login.html"的元素,得到它的文本。
jxNodes = jxDocument.selN("//a[@href='login.html']/text()");
for (JXNode jxNode : jxNodes) {
System.out.println(jxNode);
}
}
}