一. XML作用及应用(XML:ExtensibleMarkup Language)
1. 作用:描述有关系和层次结构的数据
2. 应用:用于软件的配置文件,描述数据
注:在开发中,传统的配置文件使用的是.propeties文件。以key=value的形式。#代码注释
二. XML语法
1. XML文档声明
<?xml version=”1.0” encoding=”utf-8”?>
version:版本号,目前最高版本还是1.0
encoding:指定编码,如果不写,默认的为utf-8。
注意: 当我们用记事本或其它编辑器编辑xml文件,保存时默认使用的是系统编码。xml文件保存的编码应与xml里encoding编码一致,否则会因为写入及读取的编码表不同而出现错误或乱码的情况。
standalone:设置该xml文件是否独立存在
2. 元素(ELEMENT)
元素也称为标签,必须要用结束标签
如果元素中没有主题内容,如<tag></tag>可以写成<tag/>
元素中不能交叉嵌套
一个xml文件有且只能有一个根元素
xml不会忽略空格、回车、制表符
不要以xml开头,因为xml作为保留的存在
命名规范:可以用字母、数字、下划线、减号、英文句点。严格区分大小写
3. 属性(ATTLIST)
命名规范与元素相同
属性名不能重复,属性的值必须要以单引号或双引号引起来
属性可以用元素的形式代替
4. 注释<!—xxxxx-->
5. CDATA区
把元素看作为普通字符串,格式:<![CDATA[ ..... ]]>
6. 特殊字符
& => &
< => <
> => >
" => “
&apos => ‘
7. 处理指令:PI
作用:用来指挥软件如何解析XML文档。
语法:<?开头 ?>结尾
常用的指令:xml-stylesheet引入样式
三. 约束DTD
DTD:Document Type Definition文档类型定义
作用:约束XML编写
DTD文件保存到磁盘上时必须使用utf-8
引用DTD的方式:
1. 引用本地的DTD文件
<!DOCTYPE 根节点名称 SYSTEM “DTD路径名称”>
2. 引用外部公共的DTD文件
<!DOCTYPE 根节点名称 PUBLIC “DTD名称” “DTD的URL”>
语法:
1. 元素<ELEMENT>
例:<!ELEMENT 元素名称 使用规则>
使用规则:
(#PCDATA):普通字符串数据
EMPTY:此元素为空元素
ANY:表示此元素的主体内容可以为任何类型
(子元素):指示此元素有哪些子元素。
//如果是逗号隔开,表明必须按照声明顺序去编写XML文档,如果子元素用 | 隔开,表明任选其一。
可以用*,?,+表示元素出现的次数:*(0次或一次或多次) ?(0次或一次) +(一次或多次) 什么都没有表示必须出现一次。
2. 属性<ATTLIST>
例:<!ATTLIST 元素名称 属性名 属性值类型 设置说明属性名 属性值类型 设置说明>
属性值类型:
CDATA:字符类型
ENUMERATED:枚举,只能从枚举中任选其一
ID:表示属性值必须是唯一
设置说明:
#REQUIRED:表示此属性必须要写
#IMPLIED:可选的属性
#FIXED:取值为一个固定值 #FIXED“值”
直接值:默认值
3. 实体
引用实体:在DTD中定义,在XML中使用
语法:<!ENTITY 实体名称 “内容”>
引用:&实体名称;
参数实体:在DTD中定义,在DTD中使用
语法:<!ENTITY %实体名称 “内容”>
引用:%实体名称;
四. XML编程
1. DOM:document object model
好处:CRUD比较方便快捷。
缺点:因为dom解析时会将整个xml文件加载至内存,变成一个对象,占用内存较大。还可能导致内存溢出。
DocumentBuilder dBuilder = DocumentBuilerFactory.newInstance().newDocumentBuilder();
Document document = dBuilder.parse(“xml路径”);
实例:以下文件示例中有对XML文件各种操作
ReadBook.java
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.OutputStreamWriter;
-
- import javax.xml.parsers.DocumentBuilder;
- import javax.xml.parsers.DocumentBuilderFactory;
- import javax.xml.transform.Transformer;
- import javax.xml.transform.TransformerConfigurationException;
- import javax.xml.transform.TransformerFactory;
- import javax.xml.transform.dom.DOMSource;
- import javax.xml.transform.stream.StreamResult;
-
- import org.w3c.dom.Attr;
- import org.w3c.dom.Document;
- import org.w3c.dom.Element;
- import org.w3c.dom.NamedNodeMap;
- import org.w3c.dom.Node;
- import org.w3c.dom.NodeList;
-
- public class ReadBook {
-
- public static void main(String[] args) throws Exception {
-
- DocumentBuilderFactory dBuilderFactory = DocumentBuilderFactory
- .newInstance();
- DocumentBuilder dBuilder = dBuilderFactory.newDocumentBuilder();
- Document document = dBuilder.parse("src\\day\\o1\\book.xml");
-
- // test1(document);
- // test2(document);
- // test3(document);
- // test4(document);
- // test5(document);
- // test6(document);
- test7(document);
- }
-
- // 1、得到某个具体的节点内容
- public static void test1(Document document) {
- Node node = document.getElementsByTagName("作者").item(0);
-
- System.out.println(node.getTextContent());
- }
-
- // 2、遍历所有元素节点
- // public static void test2(Document document) {
- // Node root = document.getElementsByTagName("书架").item(0);
- // list(root);
- // }
- //
- // public static void list(Node root) {
- // if (root instanceof Element)
- // System.out.println(root.getNodeName());
- // NodeList nodeList = root.getChildNodes();
- // for (int x = 0; x < nodeList.getLength(); x++) {
- // list(nodeList.item(x));
- // }
- // }
- //上面的代码改成
- public static void test2(Node node) {
-
- if (node.getNodeType() == node.ELEMENT_NODE)
- System.out.println(node.getNodeName());
- NodeList nodeList = node.getChildNodes();
- for (int x = 0; x < nodeList.getLength(); x++) {
- test2(nodeList.item(x));
- }
- }
-
- // 3、修改某个元素节点的主体内容
- public static void test3(Document document) throws Exception {
-
- Element author = (Element) document.getElementsByTagName("作者").item(0);
-
- author.setTextContent("zhangxiaoxiang");
-
- TransformerFactory tfFactory = TransformerFactory.newInstance();
- Transformer tf = tfFactory.newTransformer();
- tf.transform(new DOMSource(document), new StreamResult(
- new OutputStreamWriter(new FileOutputStream(
- "src\\day\\o1\\book.xml"), "gbk")));
- }
-
- // 4、向指定元素节点中增加子元素节点
- public static void test4(Document document) throws Exception {
-
- Element book = (Element) document.getElementsByTagName("书").item(0);
- Element newChild = document.createElement("类型");
- Element refChild = (Element) document.getElementsByTagName("作者")
- .item(0);
-
- newChild.setTextContent("计算机类");
- book.insertBefore(newChild, refChild);
-
- TransformerFactory tfFactory = TransformerFactory.newInstance();
- Transformer tf = tfFactory.newTransformer();
- tf.transform(new DOMSource(document), new StreamResult(
- new OutputStreamWriter(new FileOutputStream(
- "src\\day\\o1\\book.xml"), "gbk")));
- }
-
- // 5、向指定元素节点上增加同级元素节点
- public static void test5(Document document) throws Exception {
-
- Element bookName = (Element) document.getElementsByTagName("书名")
- .item(1);
- Element newChild = document.createElement("类型");
- newChild.setTextContent("计算机类");
-
- Element parentNode = (Element) bookName.getParentNode();
- parentNode.appendChild(newChild);
-
- TransformerFactory tfFactory = TransformerFactory.newInstance();
- Transformer tf = tfFactory.newTransformer();
- tf.transform(new DOMSource(document), new StreamResult(
- new OutputStreamWriter(new FileOutputStream(
- "src\\day\\o1\\book.xml"), "gbk")));
- }
-
- // 6、删除指定元素节点
- public static void test6(Document document) throws Exception {
- Element price = (Element) document.getElementsByTagName("售价").item(0);
- price.getParentNode().removeChild(price);
-
- TransformerFactory tfFactory = TransformerFactory.newInstance();
- Transformer tf = tfFactory.newTransformer();
- tf.transform(new DOMSource(document), new StreamResult(
- new OutputStreamWriter(new FileOutputStream(
- "src\\day\\o1\\book.xml"), "gbk")));
- }
-
- // 7、操作XML文件属性
- public static void test7(Document document) throws Exception {
- Element book = (Element) document.getElementsByTagName("书").item(0);
- // System.out.println(book.getAttribute("出版社"));
- //
- // book.setAttribute("出版社", "黑马出版社");
-
- NamedNodeMap nodeMap = book.getAttributes();
- for (int x = 0; x < nodeMap.getLength(); x++) {
-
- Attr attr = (Attr) nodeMap.item(x);
- System.out.println(attr.getName() + ":::" + attr.getValue());
- }
-
- // TransformerFactory tfFactory = TransformerFactory.newInstance();
- // Transformer tf = tfFactory.newTransformer();
- // tf.transform(new DOMSource(document), new StreamResult(
- // new OutputStreamWriter(new FileOutputStream(
- // "src\\day\\o1\\book.xml"), "gbk")));
- }
- }
book.xml
- <?xml version="1.0" encoding="gbk" standalone="no"?><书架>
- <书 出版社="黑马出版社" 责任人="我">
- <书名>JavaOOP</书名>
- <类型>计算机类</类型>
- <作者>zhangxiaoxiang</作者>
- </书>
- <书>
- <书名>JavaScript</书名>
- <作者>王老师</作者>
- <售价>5.00</售价>
- <类型>计算机类</类型>
- </书>
- </书架>
2. SAX:
好处:读取xml文件快,占用内存小。因为在读取的方式是一行一行读取。只适合xml文件的读取。不适合CUD操作。读一行处理一行
实例:
//获取SAX解析器
SAXParser parser =SAXParserFactory.newInstance().newSAXParser();
//通过SAX解析器得到读取器
XMLReader reader = parser.getXMLReader();
//注册内容处理器
reader.setContentHandler( 传入ContentHandler的实现类);
1. 此处可以自己写一个类实现ContentHandler接口,覆盖所有方法。
2. 还可以写一个内部类,因为DefaultHadler是ContentHandler的实现类,我们可以写一个内部类继承DefaultHadler,复写所需的方法。
需要了解到所有的方法用处及运行过程。
实例:
1. 查找指定的作者名。 2. 把读取到的数据封闭到JAVABEAN中。XML文件同为上面的BOOK.XML文件
SAXReadDemo.java
- package jaxp.sax;
-
- import java.io.IOException;
-
- import javax.xml.parsers.ParserConfigurationException;
- import javax.xml.parsers.SAXParser;
- import javax.xml.parsers.SAXParserFactory;
-
- import org.xml.sax.Attributes;
- import org.xml.sax.SAXException;
- import org.xml.sax.XMLReader;
- import org.xml.sax.helpers.DefaultHandler;
-
- public class SAXReadDemo {
-
- public static void main(String[] args) throws ParserConfigurationException,
- SAXException, IOException {
- // 得到sax解析器
- SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
- // 得到读取器
- XMLReader reader = parser.getXMLReader();
- // 注册内容处理器
- reader.setContentHandler(new DefaultHandler() {
- private boolean flag = false;
- private int authorIndex = 0;
- @Override
- public void startElement(String uri, String localName,
- String qName, Attributes attributes) throws SAXException {
- if("作者".equals(qName)){
- flag = true;
- }
- }
-
- @Override
- public void characters(char[] ch, int start, int length)
- throws SAXException {
- if(flag && authorIndex==1){
- System.out.println(new String(ch,start,length));
- }
- }
-
- @Override
- public void endElement(String uri, String localName, String qName)
- throws SAXException {
- if("作者".equals(qName)){
- authorIndex++;
- }
- flag = false;
- }
- });
- // 读取xml文档
- reader.parse("src\\book.xml");
- }
-
- }
BeanRead.java
- package jaxp.sax;
-
- public class BookBean {
-
- private String press;
- private String editer;
- private String bookname;
- private String author;
- private String type;
-
- public BookBean() {
- // TODO Auto-generated constructor stub
- }
-
- public BookBean(String press, String editer, String bookname,
- String author, String type) {
- super();
- this.press = press;
- this.editer = editer;
- this.bookname = bookname;
- this.author = author;
- this.type = type;
- }
-
- public String getPress() {
- return press;
- }
-
- public void setPress(String press) {
- this.press = press;
- }
-
- public String getEditer() {
- return editer;
- }
-
- public void setEditer(String editer) {
- this.editer = editer;
- }
-
- public String getBookname() {
- return bookname;
- }
-
- public void setBookname(String bookname) {
- this.bookname = bookname;
- }
-
- public String getAuthor() {
- return author;
- }
-
- public void setAuthor(String author) {
- this.author = author;
- }
-
- public String getType() {
- return type;
- }
-
- public void setType(String type) {
- this.type = type;
- }
-
- @Override
- public String toString() {
- return "BookBean [press=" + press + ", editer=" + editer
- + ", bookname=" + bookname + ", author=" + author + ", type="
- + type + "]";
- }
-
-
- }
Read2JavaBean.java
- package jaxp.sax;
-
- import java.util.ArrayList;
- import java.util.List;
-
- import javax.xml.parsers.SAXParser;
- import javax.xml.parsers.SAXParserFactory;
-
- import org.xml.sax.Attributes;
- import org.xml.sax.SAXException;
- import org.xml.sax.XMLReader;
- import org.xml.sax.helpers.DefaultHandler;
-
- public class Read2JavaBean {
-
- /**
- * 读取xml文件并将数据封装至javabean中
- */
- static final List list = new ArrayList();
-
- public static void main(String[] args) throws Exception {
-
- // 得到sax解析器
- SAXParser sax = SAXParserFactory.newInstance().newSAXParser();
- // 得到读取器
- XMLReader reader = sax.getXMLReader();
- // 注册内容处理器
- reader.setContentHandler(new DefaultHandler() {
-
- private BookBean book = null;
- private String current = null;
-
- @Override
- public void startElement(String uri, String localName,
- String qName, Attributes attributes) throws SAXException {
-
- if ("书".equals(qName)) {
- book = new BookBean();
-
- book.setPress(attributes.getValue(0));
- book.setEditer(attributes.getValue(1));
- }
-
- if ("书名".equals(qName))
- current = qName;
-
- if ("作者".equals(qName))
- current = qName;
-
- if ("类型".equals(qName))
- current = qName;
- }
-
- @Override
- public void characters(char[] ch, int start, int length)
- throws SAXException {
- if ("书名".equals(current))
- book.setBookname(new String(ch, start, length));
- if ("作者".equals(current))
- book.setAuthor(new String(ch, start, length));
- if ("类型".equals(current))
- book.setType(new String(ch, start, length));
- }
-
- @Override
- public void endElement(String uri, String localName, String qName)
- throws SAXException {
-
- if ("书".equals(qName)) {
- list.add(book);
- book = null;
- }
-
- current = null;
- }
- });
- // 读取xml文件内容
- reader.parse("src\\book.xml");
-
- System.out.println(list);
- }
- }
3. DOM4J解析器
结合DOM和SAX的优点,在读取时用SAX的原理,在CUD操作时用DOM原理。
实例:XML文件进行CRUD操作。XML文件同为上面的BOOK.XML文件
Dom4JDemo.java
4. 单元测试JUNIT
在Eclipse中可以新建一个Junit Test Case文件,用于对某个类的方法进行测试。
@Before 每测试一个方法之前,都读取此方法。执行多个方法,此方法也执行多次。
@After 每测试一个方法之后,都读取此方法。执行多个方法,此方法也执行多次。
@BeforeClass 此上述一样,区别在于,无论执行多少方法,此方法只执行一次。
@AfterClass 如上。
@Test 在要执行的测试方法前加@Test
(Timeout=1000) 代表测试的方法执行的时间,如果超过此设置的时间,则测试会不通过。
(exception=java.lang.NullPointException.class) 代表测试的方法需要返回一个指定的异常。
Assert.assertEquals(期待值,实际值);
此系列方法很多,还有判断返回是不是Boolean型的true。具体查API。
5. XPATH
用于在读取XML中元素时能快速定位一个指定的标签。
Node node = document.selectSingleNode(“//书[1]”);
关于Xpath的使用规则查看Xpath的文档。
6. 学生成绩 案例:
分层结构:
UI---JAVABEAN---DAO---UTILS---DB
Utils中的方法为static方法。
Dao 中封装所有对数据库进行操作的方法。如果操作的方式不同,可以创建多个Dao包。然后抽取成Interface。多个Dao包实现此Interface。方便以后选择其它操作方式。
Utils包对于异常的处理原则:
可以抛出:但是调用该工具类的必须处理。也可以不抛
非工具类的异常的处理原则:
看调用者能不能处理,不能处理则不抛。
异常转译和异常链
五. Schema约束
扩展名:xsd 本身也是一个xml文件
1、查看Schema文档,找到根元素,在xml中先编写根元素
<?xmlversion="1.0" encoding="gbk"?>
<书架>
</书架>
2、思考:书架来自哪个名称空间。
使用xmlns关键字(xml namespace)来声明来自的命名空间(查阅schema文档中targetNamespace指定的值)
<?xmlversion="1.0" encoding="gbk"?>
<itheima:书架 xmlns:itheima="http://www.itcast.cn">
</itheima:书架>
3、思考:名称空间对应的xsd文件在何方?
使用schemaLocation来说明名称空间和xsd文件的对应关系。
有2个取值:名称空间和xsd文件路径,两者之间用空格、回车、换行分隔
<?xmlversion="1.0" encoding="gbk"?>
<itheima:书架 xmlns:itheima="http://www.itcast.cn"
schemaLocation="http://www.itcast.cnbook.xsd">
</itheima:书架>
4、思考:schemaLocation又哪来的呢?来自W3C的标准名称空间
http://www.w3.org/2001/XMLSchema-instance
<?xmlversion="1.0" encoding="gbk"?>
<itheima:书架 xmlns:itheima="http://www.itcast.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.itcast.cnbook.xsd">
</itheima:书架>