Java
学习内容
XML | XML解析技术 | XPath | 设计模式 |
---|---|---|---|
在有些业务场景下,存储数据或者传输数据给别人的时候,数据需要满足优点的规范进行组织 | XML文件存储的数据需要提取出来 | 如何方便的在XML文件中进行数据的检索 | 开发中还有一些比较常见的设计模式需要掌握,理解设计模式有利于理解某些程序 |
XML
概述
- XML是可扩展标记语言(eXtensible Markup Language)的缩写,它是一种数据表示格式,可以描述非常复杂的数据结构,常用于数据传输和存储数据
XML的几个特点和使用场景
- 一是纯文本,默认使用UTF-8编码,二是可嵌套
- 如果把XML内容存位文件,那么它就是一个XML文件
- XML使用场景:XML内容经常被当成消息进行网络传输,或者作为配置文件用于存储系统的信息
作用
- 用于进行存储数据和传输数据
- 作为软件的配置文件
创建
- 就是创建一个XML类型的文件,要求文件的后缀必须使用xml,如hello_world.xml
语法规则
- XML文件的后缀名为:XML
- 文当声明必须在第一行
<?xml version="1.0" encoding="UTF-8"?>
//version:XML默认版本号码、该属性是必须存在的
//encoding:本XML文件的编码
标签(元素)规则
- 标签由一对尖括号和合法标识符组成:
,必须存在一个根标签,有且只能有一个 - 标签必须成对出现,有开始,有结束:
- 特殊的标签可以步成对,但是必须有结束标记,如
- 标签中可以定义属性,属性和标签名空格隔开,属性值必须用符号引起来
- 标签需要正确嵌套
其他组成
-
XML文件中可以定义注释信息:
-
XML文件中可以存在以下特殊字符
-
< < 小于 > > 大于 & & 和号 ' ' 单引号 " " 双引号
-
-
XML文件中可以存在CDATA区:
总结
XML的组成格式要求是什么样子的
-
文件后缀必须是xml
-
文档声明必须是第一行
-
必须存在一个根目录,有且只有一个
-
XML文件中可以定义注释信息:
-
标签必须成对出现,有开始就要有结束标签
-
必须能够正确的嵌套
文档约束
- 用来限定xml文件中的标签以及属性应该怎么写。
- 以此强制约束程序员必须按照文档约束的规定来编写xml文件
文档约束分类
- DTD
- schema
方式一:DTD约束
后缀名:.dtd
- 作用
- 约束XML文件的编写
- 问题
- 不能约束具体的数据类型
<!ELEMENT 书架 (书+)>
<!ELEMENT 书 (书名,作者,售价)>
<!ELEMENT 书名 (#PCDATA)>
<!ELEMENT 作者 (#PCDATA)>
<!ELEMENT 售价 (#PCDATA)>
方式二:schema
后缀名:.xsd
- schema可以约束具体数量的数据类型,约束能力上更加强大
- schema本身也是一个xml文件,本身也受到其他约束文件的要求,所以编写的更加严谨
优点
- 可以约束XML文件的标签内容格式,以及具体的数据类型
其他文件----约束---->schema文件----约束---->XML
<?xml version="1.0" encoding="UTF-8" ?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itcast.cn"
elementFormDefault="qualified">
<!--targetNamespace:申明约束文档的地址(命名空间)-->
<element name="书架">
<!--写子元素-->
<complexType>
<!--maxOccurs = "unbounded":书架下的子元素可以有任意多个-->
<sequence maxOccurs="unbounded">
<element name="书">
<!--写子元素-->
<complexType>
<sequence>
<element name="书名" type="string"/>
<element name="作者" type="string"/>
<element name="售价" type="double"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
<?xml version="1.0" encoding="ISO-8859-1"?>
<书架 xmlns="http://www.itcast.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.itcast.cn data2.xsd">
<书>
<书名>java</书名>
<作者>liu</作者>
<售价>99.9</售价>
</书>
</书架>
XML解析技术
XML的数据作用?最终需要这么处理?
- 存储数据,做配置信息,进行数据传输
- 最终需要被程序进行读取,解析里面的信息
概念
- 使用程序读取XML中的数据
解析方式
- SAX解析
- DOM解析
Dom解析
常用解析技术
Dom4J
常见解析工具
名称 | 说明 |
---|---|
JAXP | SUN公司提供的一套XML的解析API |
JDOM | JDOM是一个开源项目,它基于树型结构,利用JAVA的技术对XML文档实现解析、生成、序列化以及多种操作 |
dom4j | 是JDOM的升级品,用来读写XML文件的,具有性能优异、功能强大和及其易使用的特点,它的性能超过孙公司官方的dom技术,同时它也是一个开发源码的软件,Hibernate也用他来读写配置文件 |
jsoup | 功能强大DOM方式的XML解析开发包,尤其对HTML解析更加方便 |
解析文档对象模型
Document:整个xml文档
Element:标签
Attribute:属性
Text对象:文本内容
全部实现Node对象接口
得到Document对象
SAXReader类
构造器/方法 | 说明 |
---|---|
public SAXReader() | 创建Dom4J的解析器对象 |
Document read(String url) | 加载XML文件成为Document对象 |
Document类
方法名 | 说明 |
---|---|
Element getRootElement() | 获得根元素对象 |
解析XML的元素、属性、文本
方法名 | 说明 |
---|---|
List |
得到当前元素下所有子元素 |
List |
得到当前元素下指定名字的子元素返回集合 |
Element element(String name) | 得到当前元素下指定名字的子元素,如果有很多名字相同则返回第一个 |
String getName() | 得到元素名 |
String attributeValue(String name) | 通过属性名直接得到属性值 |
String elementText(子元素名) | 得到指定名称的子元素文本 |
String getText() | 得到文本 |
package com.yu.Day1015Demo;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
public class Dmo4JitheimaDemo01 {
@Test
public void parseXMLData() throws Exception{
//1. 创建一个Dom4J的解析器对象,代表了整个dom4j框架
SAXReader saxReader = new SAXReader();
//2.把xml文件加载到内存中成为一个Document文档对象
// Document document = saxReader.read(new FileInputStream("xmldata\\hello_world.xml"));//需要通过模块名去定位
//相当于直接取src下的文件,注意:getResourceAsStream中的/是直接取src先寻找文件
InputStream is = Dmo4JitheimaDemo01.class.getResourceAsStream("/hello_world.xml");
Document document = saxReader.read(is);
//3.获取根元素
Element root = document.getRootElement();
System.out.println(root.getName());
//4.得到根元素下的全部子元素对象
List<Element> sonEles = root.elements();
//查指定元素的一堆
// List<Element> sonEles = root.elements("stu");
for (Element sonEle : sonEles) {
System.out.println(sonEle.getName());
}
//查指定元素的一个,如果用重复项默认拿第一个
Element stuEle = root.element("stu");
System.out.println(stuEle.getName());
//获取子元素文本
System.out.println(stuEle.elementText("name"));
//获取子元素文本,并去掉文本前后的空格
System.out.println(stuEle.elementTextTrim("name"));
//根据元素获取属性值
Attribute id = stuEle.attribute("id");
System.out.println(id.getName()+"---->"+id.getValue());
System.out.println(stuEle.attributeValue("id"));
//获得当前元素下的子元素对象
Element xb = stuEle.element("sex");
System.out.println(xb.getText());
}
}
XML检索技术:Xpath
下载地址http://www.java2s.com/Code/Jar/j/Downloadjaxen112jar.htm#google_vignette
简介
- XPath在解析XML文档方法提供了——独树一帜的路径思想,更加优雅、高效
- XPath使用路径表达式来定位XML文档中的元素节点或属性节点
- 路径表达式:/元素/子元素/孙元素
Document中与Xpath相关的API
方法名 | 说明 |
---|---|
Node selectSingleNode("表达式") | 获取符合表达式的唯一元素 |
List |
获取符合表达式的元素集合 |
Xpath的四大路径
- 绝对路径
- 相对路径
- 全文检索
- 属性查找
XPath:绝对路径
- 采用绝对路径获取从根节点开始逐层查找/contactList/contact/name节点列表并打印信息
方法名 | 说明 |
---|---|
/根元素/子元素/孙元素 | 从根元素开始,一级一级向下查找,不能跨级 |
Xpath:相对路径
- 先得到根节点contactList
- 在采用相对路径获取下一级contact节点的name子节点并打印信息
方法名 | 说明 |
---|---|
./子元素/孙元素 | 从当前元素开始,一级一级向下查找,不能跨级 |
Xpath:全文搜索
- 直接全文搜索所有name元素并打印
方法名 | 说明 |
---|---|
//contact | 找contact元素,无论元素在哪里 |
//contact/name | 找contact,无论在哪一级,单name一定是contact的子节点 |
//contact//name | contact无论哪一种,name只要是contact的子孙元素都可以找到 |
Xpath:属性查找
- 在全文搜索属性或者带属性的元素
方法名 | 说明 |
---|---|
//@属性名 | 查找属性对象,无论是哪个元素,只要有这个属性即可 |
//元素[@属性名] | 查找元素对象,全文搜索指定元素名和属性名 |
//元素//[@属性名='值'] | 查找元素对象,全文搜索指定元素名和属性名,并且属性值相等 |
package com.yu.Day1015Demo;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.util.List;
public class XpathDemo {
//绝对路径
@Test
public void parse01() throws Exception{
//创建解析器对象
SAXReader saxReader = new SAXReader();
//把xml文件加载Document文档对象
Document document = saxReader.read(XpathDemo.class.getResourceAsStream("/hello_world.xml"));
//c检索全部的name
List<Node> nameNodes = document.selectNodes("/student/stu/name");
for (Node nameNode : nameNodes) {
Element nameEle = (Element)nameNode;
System.out.println(nameEle.getName()+"->"+nameEle.getTextTrim());
}
}
//相对路径
@Test
public void parse02() throws Exception{
//创建解析器对象
SAXReader saxReader = new SAXReader();
//把xml文件加载Document文档对象
Document document = saxReader.read(XpathDemo.class.getResourceAsStream("/hello_world.xml"));
Element root = document.getRootElement();
//c检索全部的name
List<Node> nameNodes = root.selectNodes("./stu/name");
for (Node nameNode : nameNodes) {
Element nameEle = (Element)nameNode;
System.out.println(nameEle.getName()+"->"+nameEle.getTextTrim());
}
}
//全文检索yuan's
//元素 在全文找这个元素
//元素1/元素2 子啊全文找元素1下的一级元素2
//元素1//元素2 子啊全文找元素1下面的全部元素2
@Test
public void parse03() throws Exception {
//创建解析器对象
SAXReader saxReader = new SAXReader();
//把xml文件加载Document文档对象
Document document = saxReader.read(XpathDemo.class.getResourceAsStream("/hello_world.xml"));
//检索数据
// List<Node> nameNodes = document.selectNodes("//name");
List<Node> nameNodes = document.selectNodes("//stu/name");
for (Node nameNode : nameNodes) {
Element nameEle = (Element)nameNode;
System.out.println(nameEle.getName()+"->"+nameEle.getTextTrim());
}
}
//属性查找
//@属性名称 在全文检索属性对象
//元素[@属性名称] 在全文检索包含该属性的元素对象
//元素[@属性名称=值] 在全文检索包含该属性的元素且属性值为该值的元素对象
@Test
public void parse04() throws Exception{
//创建解析器对象
SAXReader saxReader = new SAXReader();
//把xml文件加载Document文档对象
Document document = saxReader.read(XpathDemo.class.getResourceAsStream("/hello_world.xml"));
//c检索全部的name
List<Node> nameNodes = document.selectNodes("//@id");
for (Node nameNode : nameNodes) {
Attribute attribute = (Attribute)nameNode;
System.out.println(attribute.getName()+"->"+ attribute.getValue());
}
//查询name元素包含id属性的
// Node node = document.selectSingleNode("//name[@id]");
Node node = document.selectSingleNode("//name[@id=888]");
Element element = (Element) node;
System.out.println(element.getTextTrim());
}
}
总结
Xpath作用
- 检索XML文件中的信息
四大类
- 绝对路径:/根元素/子元素/孙元素
- 相对路径:./子元素/孙元素
- 全文检索://contact
- 属性查找://@属性名、//元素[@属性名]、//元素[@属性名='值']
设计模式
工厂模式
- (Factory Pattern) 是Java中最常用的设计模式之一,这种类型的设计模式属于创建型模式,他提供了一种获得对象的方式
作用
- 工厂的方法可以封装对象的创建细节。比如:为该对象进行加工和数据注入
- 可以实现类与类之间的解耦操作(核心思想)
装饰模式
- 创建一个新类,包装原始类,从而在新类中提升原始类的功能
作用
- 装饰模式指在不改变原类的基础上,动态的扩展一个类的功能
InputStream(抽象父类)
FileInputStream(实现子类,读写性能较差)
BufferedInputStream(实现子类,装饰类,读写性能高)
- 定义父类
- 定义原始类,继承父类,定义功能
- 定义装饰类,继承父类,包装原始类,增强功能!!