XML--DTD--Schema--DOM--SAX--DOM4J--XPATH

一.  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.    特殊字符

&amp;     =>   &

&lt;           =>     <

&gt;          =>     >

&quot       =>   “

&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

package dom4j;

import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public class Dom4jDemo {

	/**
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		SAXReader reader = new SAXReader();
		Document document = reader.read("src//book.xml");

		// test1(document);
		// test2(document);
		// test3(document);
		// test4(document);
		// test5(document);
		// test6(document);
		test7(document);
	}

	// 1、得到某个具体的节点内容
	public static void test1(Document document) {

		Element root = document.getRootElement();
		List<Element> lists = root.elements();
		String author = lists.get(1).elementText("作者");
		System.out.println(author);
	}

	// 2、遍历所有元素节点
	public static void test2(Document document) {
		treeWalk(document.getRootElement());
	}

	public static void treeWalk(Element element) {

		for (int x = 0; x < element.nodeCount(); x++) {

			Node node = element.node(x);
			if (node instanceof Element) {

				System.out.println(node.getName());
				treeWalk((Element) node);
			} else
				System.out.println(node.getText());
		}
	}

	// 3、修改某个元素节点的主体内容
	public static void test3(Document document) throws Exception {

		Element root = document.getRootElement();
		List<Element> list = root.elements();

		Element bookE = list.get(1);

		Element typeE = bookE.element("类型");

		typeE.setText("图书类");
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding("gbk");
		XMLWriter writer = new XMLWriter(new FileWriter("src//book.xml"),
				format);
		writer.write(document);
		writer.close();
	}

	// 4、向指定元素节点中增加子元素节点
	public static void test4(Document document) throws Exception {

		Element root = document.getRootElement();

		Element book = root.addElement("书");
		book.addAttribute("出版社", "传智");

		book.addElement("书名").addText("html");
		book.addElement("作者").addText("王昭廷");
		book.addElement("类型").addText("动画片");

		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding("gbk");
		XMLWriter writer = new XMLWriter(new FileWriter("src//book.xml"),
				format);
		writer.write(document);
		writer.close();
	}

	// 5、向指定元素节点上增加同级元素节点
	public static void test5(Document document) throws Exception {
		Element root = document.getRootElement();

		Element bookE = root.element("书");

		Element bookNameE = bookE.element("书名");

		bookNameE.getParent().addElement("零售价").addText("32.22");

		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding("gbk");
		XMLWriter writer = new XMLWriter(new FileWriter("src//book.xml"),
				format);
		writer.write(document);
		writer.close();
	}

	// 6、删除指定元素节点
	public static void test6(Document document) throws Exception {

		Element root = document.getRootElement();

		Element book = root.element("书");
		Element price = book.element("零售价");

		price.getParent().remove(price);

		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding("gbk");
		XMLWriter writer = new XMLWriter(new FileWriter("src//book.xml"),
				format);
		writer.write(document);
		writer.close();
	}

	// 7、操作XML文件属性
	public static void test7(Document document) throws Exception {

		Element root = document.getRootElement();
		Element book = root.element("书");
		for (Iterator<Attribute> it = book.attributeIterator(); it.hasNext();) {

			Attribute att = it.next();

			System.out.println(att.getName() + "=" + att.getValue());
		}
	}
}


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:书架>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值