XML基础

XML编程

主要内容

l  XML及其语法

l  XML约束之DTD

l  XML编程(CRUD---CreateRead Update Delete)

l  XML约束之Schema


XML及其语法

什么是XML

l  XML是指可扩展标记语言(eXtensibleMarkup Language),它是一种标记语言,很类似HTML。它被设计的宗旨是传输数据,而非显示数据

l  XML标签没有被预定义,需要用户自行定义标签

l  XML技术是W3C组织(WorldWide Web Consortium万维网联盟)发布的,目前遵循的是W3C组织于2000年发布的XML1.0规范。

l  XML被广泛认为是继Java之后在Internet上最激动人心的新技术。


XML技术用于解决什么问题?

l   在现实生活中存在大量有关系的数据,如右图所示。

l   问题:这样的数据该如何表示并交给计算机处理呢?


XML技术用于解决什么问题?

l  XML语言出现的根本目的在于描述向上图那种有关系的数据。

l  XML是一种通用的数据交换格式

l  XML语言中,它允许用户自定义标签。一个标签用于描述一段数据;一个标签可分为开始标签和结束标签,在起始标签之间,又可以使用其它标签描述其它数据,以此来实现数据关系的描述。

l  XML中的数据必须通过软件程序来解析执行或显示,如IE;这样的解析程序称之为Parser(解析器)

<?xmlversion="1.0" encoding="UTF-8"?>

<中国>

       <北京>

           <海淀></海淀>

           <丰台></丰台>

       </北京>

       <山东>

           <济南></济南>

           <青岛></青岛>

       </山东>

       <湖北>

           <武汉></武汉>

           <荆州></荆州>

       </湖北>

</中国>


XML常见应用

l   Java开发中,传统的配置文件是*.properties属性文件(key=value),而XML表示的数据更为丰富。

l  XML技术除用于描述有关系的数据外,还经常用作软件配置文件,以描述程序模块之间的关系。(如后面将要学习到的StrutsSpringHibernate都是基于XML作为配置文件的)

l   在一个软件系统中,通过XML配置文件可以提高系统的灵活性。即程序的行为是通过XML文件来配置的,而不是硬编码。


XML文档的组成

l  一个XML文件一般由以下几部分组成:

•      文档声明

•      元素

•      元素的属性

•      注释

•      CDATA

•      特殊字符

•     处理指令(PI:ProcessingInstruction)


文档声明

l  在编写XML文档时,需要先使用文档声明来声明XML文档。且必须出现在文档的第一行

l  最简单的语法:<?xml version=1.0?>

l  encoding属性说明文档所使用的字符编码,默认为UTF-8保存在磁盘上的文件编码要与声明的编码一致。

       如:<?xmlversion=1.0encoding=GB2312?>

l  standalone属性说明文档是否独立,即是否依赖其他文档。

       如:<?xmlversion=1.0standalone=yes?>

 

元素(1)

l  XML元素指XML文件中出现的标签。一个标签分为起始和结束标签(不能省略)。一个标签有如下几种书写形式:

•     包含标签主体:<mytag>somecontent</mytag>

•     不含标签主体:<mytag/> ==   <mytag></mytag>     <br/><hr/>

l  一个标签中可以嵌套若干子标签,但所有标签必须合理的嵌套,不允许有交叉嵌套。

•     <mytag1><mytag2></mytag1></mytag2>   WRONG

l  一个XML文档必须有且仅有一个根标签,其他标签都是这个根标签的子标签或孙标签。

 

元素(2)

l  XML中不会忽略主体内容中出现的空格和换行。


元素(3)--元素命名规范

l  元素(标签)的名称可以包含字母、数字、减号、下划线和英文句点,但必须遵守下面的一些规范:

•     严格区分大小写;<P> <p>

•     只能以字母或下划线开头;abc _abc

•      不能以xml(XMLXml)开头----W3C保留日后使用;

•     名称字符之间不能有空格或制表符;ab

•     名称字符之间不能使用冒号;(有特殊用途)


元素的属性

l  一个元素可以有多个属性,每个属性都有它自己的名称和取值,例如:<mytagname=value/>

l  属性值一定要用引号(单引号或双引号)引起来。

l  属性名称的命名规范与元素的命名规范相同

l  元素中的属性是不允许重复的

l  XML技术中,标签属性所代表的信息也可以被改成用子元素的形式来描述,例如:


注释

l  XML中的注释语法为:<!--这是注释-->

l  注意:

•      XML声明之前不能有注释

•      注释不能嵌套,例如:



CDATA

l  CDATACharacterData的缩写

l  作用:把标签当做普通文本内容;

l  语法:<![CDATA[内容]]>

 

特殊字符

l  对于一些特殊字符,若要在元素主体内容中显示,必须进行转义。



处理指令

l  处理指令,简称PI(ProcessingInstruction)

l  作用:用来指挥软件如何解析XML文档。

l  语法:必须以“<?作为开头,以“?>作为结尾。

l  常用处理指令:

•     XML声明:<?xmlversion=1.0encoding=GB2312?>

•      xml-stylesheet指令:

•    作用:指示XML文档所使用的CSS样式XSL

 XML约束之DTD

为什么需要约束

l  XML都是用户自定义的标签,若出现小小的错误,软件程序将不能正确地获取文件中的内容而报错。(如:Tomcat)

l  XML技术中,可以编写一个文档来约束一个XML的书写规范,这个文档称之为约束。

l  两个概念:

•     格式良好的XML:遵循XML语法的XML(不一定是有效的)

•     有效的XML:遵循约束文档的XML(有效的一定就是格式良好的)

l  总之:约束文档定义了在XML中允许出现的元素名称、属性及元素出现的顺序等等。


常用的约束技术

l  XML DTD

l  XDR

l  SOX

l  XML Schema

 

DTD快速入门

l  DTD(Document TypeDefinition):文档类型定义。

l  作用:约束XML的书写规范

 

验证XML的有效性

l  如何根据DTD中定义的内容来验证XML书写是否正确呢?

l  答:需要软件程序,即解析器

 

l  根据能否对XML文档进行约束模式校验,可以将解析器分为两类:

•     非校验解析器,如IE

•      校验解析器


编程校验XML文档的正确性


编写DTD的方式

l   DTD约束文档可以在XML文档中直接定义,也可以作为单独的文档进行编写(单独的文档必须以UTF-8编码进行保存)

l   XML文档中编写DTD示例

 

引入外部DTD文档

l  XML使用DOCTYPE声明语句来指明它所遵循的DTD文档,有两种形式:

•      当引用的DTD文档在本地时,采用如下方式:

<!DOCTYPE根元素SYSTEMDTD文档路径”>

如:<!DOCTYPE书架SYSTEM book.dtd>

•      当引用的DTD文档在公共网络上时,采用如下方式:

<!DOCTYPE根元素PUBLICDTD名称”DTD文档的URL>

如:<!DOCTYPEweb-app PUBLIC

       "-//Sun Microsystems, Inc.//DTD WebApplication 2.3//EN"

       "http://java.sun.com/dtd/web-app_2_3.dtd">


DTD语法细节

l  DTD文档的语法主要涉及以下内容的定义:

•      定义元素

•      定义属性

•      定义实体


DTD-定义元素

l  DTD文档中使用ELEMENT关键字来声明一个XML元素。

l  语法:<!ELEMENT 元素名称使用规则>

•       使用规则:

•     (#PCDATA):指示元素的主体内容只能是普通的文本.(ParsedCharacter Data)
•     EMPTY:用于指示元素的主体为空。比如<br/>
•      ANY:用于指示元素的主体内容为任意类型。
•      (子元素):指示元素中包含的子元素

•      定义子元素及描述它们的关系:

•     如果子元素用逗号分开,说明必须按照声明顺序去编写XML文档。
: <!ELEMENT FILE (TITLE,AUTHOR,EMAIL)
•     如果子元素用“|分开,说明任选其一。
:<!ELEMENT FILE (TITLE|AUTHOR|EMAIL)
•     +*、?来表示元素出现的次数
•      如果元素后面没有+*?:表示必须且只能出现一次
•      +:表示至少出现一次,一次或多次
•      *:表示可有可无,零次、一次或多次
•      ?:表示可以有也可以无,有的话只能有一次。零次或一次
•    如:<!ELEMENT MYFILE ((TITLE*, AUTHOR?,EMAIL)* | COMMENT)>

 

DTD--定义属性1

l  DTD文档中使用ATTLIST关键字来为一个元素声明属性。

l  语法:




DTD--定义属性2

l  属性值类型:

•       CDATA:表示属性的取值为普通的文本字符串

•      ENUMERATED (DTD没有此关键字):表示枚举,只能从枚举列表中任选其一,如(鸡肉|牛肉|猪肉|鱼肉)

•       ID:表示属性的取值不能重复

l  设置说明

•       #REQUIRED:表示该属性必须出现

•       #IMPLIED:表示该属性可有可无

•      #FIXED:表示属性的取值为一个固定值。语法:#FIXED"固定值"

•       直接值:表示属性的取值为该默认值

DTD--定义属性示例



DTD--定义属性示例

l   ID表示属性的设置值为一个唯一值。

<?xml version ="1.0" encoding="GB2312" ?>

<!DOCTYPE 联系人列表[

    <!ELEMENT 联系人列表 ANY>

    <!ELEMENT 联系人(姓名,EMAIL)>

    <!ELEMENT 姓名(#PCDATA)>

    <!ELEMENT EMAIL(#PCDATA)>

    <!ATTLIST 联系人 编号 ID #REQUIRED>

]>

<联系人列表>

    <联系人 编号=“a">

          <姓名>张三</姓名>

          <EMAIL>zhang@it315.org</EMAIL>

     </联系人>

    <联系人 编号=“b">

          <姓名>李四</姓名>

          <EMAIL>li@it315.org</EMAIL>

    </联系人>

</联系人列表>

 

DTD--定义实体

l  定义实体就是为一段内容指定一个名称,使用时通过这个名称就可以引用其所代表的内容。

l  DTD文档中使用ENTITY关键字来声明一个实体。

l  实体可分为:引用实体和参数实体,两者的语法不同

 

定义引用实体

l  概念:在DTD中定义,在XML中使用

l  语法:<!ENTITY 实体名称“实体内容”>

l  引用方式(注意是在XML中使用):&实体名称;

 

定义参数实体(了解)

l  概念:在DTD中定义,在DTD中使用

l  语法:<!ENTITY % 实体名称“实体内容”>

l  引用方式(注意是在DTD中使用):%实体名称;

 

XMLDTD练习

l   XML练习题


l   DTD实例



XML编程(用Java编写解析器)

Java解析XML概述

l  XML解析方式分为两种:DOM方式和SAX方式

•      DOMDocumentObject Model,文档对象模型。这种方式是W3C推荐的处理XML的一种方式。

•      SAXSimpleAPI for XML。这种方式不是官方标准,属于开源社区XML-DEV,几乎所有的XML解析器都支持它。

l  XML解析开发包

•     JAXPSUN公司推出的解析标准实现。JDK

•     Dom4J是开源组织推出的解析开发包。(牛,大家都在用,包括SUN公司的一些技术的实现都在用)

•      JDom:是开源组织推出的解析开发包。


JAXP

l  JAXP:(Java API for XMLProcessing)开发包是JavaSE的一部分,它由以下几个包及其子包组成:

•      org.w3c.dom:提供DOM方式解析XML的标准接口

•      org.xml.sax:提供SAX方式解析XML的标准接口

•      javax.xml:提供了解析XML文档的类

l  javax.xml.parsers包中,定义了几个工厂类。我们可以通过调用这些工厂类,得到对XML文档进行解析的DOMSAX解析器对象。

•     DocumentBuilderFactory

•     SAXParserFactory


使用JAXP进行DOM解析

l  javax.xml.parsers 包中的DocumentBuilderFactory用于创建DOM模式的解析器对象DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance方法,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。



获得JAXP中的DOM解析器

l  调用DocumentBuilderFactory.newInstance() 方法得到创建DOM 解析器的工厂。

l  调用工厂对象的newDocumentBuilder方法得到DOM 解析器对象。

l  调用DOM 解析器对象的parse()方法解析XML 文档,得到代表整个文档的Document对象,进行可以利用DOM特性对整个XML文档进行操作了。


TipDOM编程

l  DOM模型(document object model)

•        DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)

•         dom中,节点之间关系如下:

•    位于一个节点之上的节点是该节点的父节点(parent)
•     一个节点之下的节点是该节点的子节点(children
•     同一层次,具有相同父节点的节点是兄弟节点(sibling
•    一个节点的下一个层次的节点集合是节点后代(descendant)
•    父、祖父节点及所有位于节点上面的,都是节点的祖先(ancestor)

•      节点类型(下页ppt


Node对象

l   Node对象提供了一系列常量来代表结点的类型,当开发人员获得某个Node类型后,就可以把Node节点转换成相应的节点对象(Node的子类对象),以便于调用其特有的方法。(查看API文档)

l   Node对象提供了相应的方法去获得它的父结点或子结点。编程人员通过这些方法就可以读取整个XML文档的内容、或添加、修改、删除XML文档的内容了。

 

DOM方式解析XML文件

l   DOM解析编程

•      1、得到某个具体的节点内容

•      2、遍历所有元素节点

•      3、修改某个元素节点的主体内容

•      4、向指定元素节点中增加子元素节点

•      5、向指定元素节点上增加同级元素节点

•      6、删除指定元素节点

•      7、操作XML文件属性

<?xml version="1.0" encoding="UTF-8" standalone="no"?><exam>
	<student examid="323" idcard="111">
		<name>Jim</name>
		<location>沈阳</location>
		<grade>89</grade>
	<age>23</age></student>
	<student examid="444" idcard="333">
		<age>24</age>
		<name>Tom</name>
		<location>大连</location>
		<grade>97</grade>
	</student>
</exam>
package cn.simplefile.xml;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
 * 实现Jaxp 的增删检查操作
 */
public class JaxpCURD {
	public static void main(String[] args) throws Exception {
		// get DocumentBuilder
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		
		//get xml file  Document
		Document document  = db.parse("src/student.xml");
//		test1(document);
//		test2(document);
//		test3(document);
//		test4(document);
//		test5(document);
//		test6(document);
//		test7(document);
		test8(document);
		
		
	}
	
	//获取某个节点的内容
	private static void test1(Document document){
		NodeList list = document.getElementsByTagName("name");
//		System.out.println(list.getLength());
		Node node = list.item(1);
		System.out.println(node.getTextContent());
	}
	
	// 遍历所有元素的节点:递归
	private static void test2(Node node){
		// 判断node是否是元素节点
		if (node.getNodeType() == Node.ELEMENT_NODE) {
			System.out.println(node.getNodeName());
		}
		// 判断它是否有孩子节点,循环遍历		
		NodeList children = node.getChildNodes();
		for (int i = 0; i < children.getLength(); i++) {
			Node n = children.item(i);
			// 递归调用
			test2(n);
		}
	}
	
	// 修改某个节点的主体内容
	private static void test3(Document document) throws Exception{
		// 得到某个第一个节点的内容容
		Node node = document.getElementsByTagName("name").item(0);
		// 修改主体内容
		node.setTextContent("Jim");
		// 更新XML文档
			// 利用Transformer的transform更新文档
			// 得到Transformer对象
		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer ts = tf.newTransformer();
		ts.transform(new DOMSource(document), new StreamResult("src/student.xml"));
	}
	
	// 向指定元素节点中增加子元素节点
	private static void test4(Document document) throws Exception{
		// 得到节点
		Node node = document.getElementsByTagName("student").item(0);
		// 创建新节点,并设置主体内容
		Element newEle = document.createElement("age");
		newEle.setTextContent("23");
		// 建立和原节点的关系
		node.appendChild(newEle);
		// 更新xml文档
		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer ts = tf.newTransformer();
		ts.transform(new DOMSource(document), new StreamResult("src/student.xml"));
	}
	
	// 向指定元素节点上增加同级元素节点
	private static void test5(Document document) throws Exception{
		// 找到需要的节点
		Node node = document.getElementsByTagName("name").item(1);
		// 创建新的节点
		Element e = document.createElement("age");
		e.setTextContent("24");
		// 由父节点完成插入操作
		node.getParentNode().insertBefore(e, node);
		// 更新xml文档
		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer ts = tf.newTransformer();
		ts.transform(new DOMSource(document), new StreamResult("src/student.xml"));
	}
	
	// 删除指定元素节点
	private static void test6(Document document) throws Exception{
		// 得到内部节点
		Node node = document.getElementsByTagName("name").item(1);
		// 用其父节点删除
		node.getParentNode().removeChild(node);
		// 更新xml文档
		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer ts = tf.newTransformer();
		ts.transform(new DOMSource(document), new StreamResult("src/student.xml"));
	}
	
	// 操作节点的属性
		// 得到节点的属性
	private static void test7(Document document){
		// 得到节点元素
		Node node = document.getElementsByTagName("student").item(0);
		// 设置节点属性
			// 如果节点是元素节点 则可以设置属性
		if (node.getNodeType() == Node.ELEMENT_NODE) {
			Element e = (Element)node;
			System.out.println(e.getAttribute("examid"));
		}
	}
	
	// 设置节点的属性
	private static void test8(Document document) throws Exception{
		// 得到节点元素
		Node node = document.getElementsByTagName("student").item(0);
		// 设置属性
		Element e = (Element) node;
		e.setAttribute("examid", "323");
		// 更新xml文档
		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer ts = tf.newTransformer();
		ts.transform(new DOMSource(document), new StreamResult("src/student.xml"));
	}
}

l  DOM编程练习

1、以如下格式的exam.xml文件为例

<?xml version="1.0" encoding="UTF-8"standalone="no"?>

<exam>

    <student idcard="111" examid="222">

       <name>张三</name>

       <location>沈阳</location>

       <grade>89</grade>

    </student>

   

    <student idcard="333" examid="444">

       <name>李四</name>

       <location>大连</location>

       <grade>97</grade>

    </student>

   

</exam>

 

2、编程实现如下功能

3、实现学生信息的添加


4、实现学生信息的查询

5、实现学生的删除功能


先建立XML文档,然后再在不同的包下写代码

cn.example.util包

package cn.example.utils;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;

/**
 * 工具类
 * 功能: 获取Document对象,更新xml文档
 */
public class XmlUtil {
	// 获取Document对象
	public static Document getDocument() throws Exception{
		DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		Document document = db.parse("src/student.xml");
		return document;
	}
	
	// 更新xml文档
	public static void write2Xml(Document document) throws Exception{
		Transformer tf = TransformerFactory.newInstance().newTransformer();
		tf.transform(new DOMSource(document), new StreamResult("src/student.xml"));
	}

}

cn.example.domain包

package cn.example.domain;
// 代表学生信息的JavaBeann
public class Student {
	private String name;
	private String location;
	private float grade;
	private String examid;// 准考证号 
	private String idcard;// 身份证号
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getLocation() {
		return location;
	}
	public void setLocation(String location) {
		this.location = location;
	}
	public float getGrade() {
		return grade;
	}
	public void setGrade(float grade) {
		this.grade = grade;
	}
	public String getExamid() {
		return examid;
	}
	public void setExamid(String examid) {
		this.examid = examid;
	}
	public String getIdcard() {
		return idcard;
	}
	public void setIdcard(String idcard) {
		this.idcard = idcard;
	}
	@Override
	public String toString() {
		return "姓名=" + name + ", 地址=" + location + ", 成绩="
				+ grade + ", 准考证号=" + examid + ", 身份证号=" + idcard;
	}
		
}

cn.example.dao包

package cn.example.dao;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import cn.example.domain.Student;
import cn.example.utils.XmlUtil;

/**
 * 完成学生类的增删改查
 */
public class StudentDao {
	boolean result = false;
	
	// 添加学生
	public boolean addStudent(Student student) {
		try {
			// 得到Document对象
			Document document = XmlUtil.getDocument();
			// 创建新元素节点和属性
			Element stu = document.createElement("student");
			stu.setAttribute("examid", student.getExamid());
			stu.setAttribute("idcard", student.getIdcard());
			// 创建子元素节点
			Element name = document.createElement("name");
			name.setTextContent(student.getName());
			Element location = document.createElement("location");
			location.setTextContent(student.getLocation());
			Element grade = document.createElement("grade");
			grade.setTextContent(student.getGrade() + "");
			// 确定他们之间的关系
			stu.appendChild(name);
			stu.appendChild(location);
			stu.appendChild(grade);
			document.getElementsByTagName("exam").item(0).appendChild(stu);
			//  更新XML文档
			XmlUtil.write2Xml(document);
			result = true;
		} catch (Exception e) {
			// 异常转义,由编译异常转为运行异常
			throw new RuntimeException(e);
		}
		return result;
	}

	// 删除学生
	public boolean removeStudent(String name) {
		boolean result = false;
	
		try {
			// 得到DOM对象
			Document document = XmlUtil.getDocument();
			// 得到要删除的节点
			NodeList list = document.getElementsByTagName("name");
			// 循环遍历所有节点
			for (int i = 0; i < list.getLength(); i++) {
				Node node = list.item(i);
				// 利用根节点删除父节点
				if (node.getTextContent().equals(name.trim())) {
					node.getParentNode().getParentNode().removeChild(node.getParentNode());
					// 更新XML文档
					XmlUtil.write2Xml(document);
					result = true;
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return result;
	}

	// 查询学生信息
	public Student queryStudent(String examid) {
		Student student = null;
		try {
			// 创建dom对象
			Document document = XmlUtil.getDocument();
			// 得到所有的student元素
			NodeList list = document.getElementsByTagName("student");
			// 循环遍历匹配与examid相等的节点
			for (int i = 0; i < list.getLength(); i++) {
				Node node = list.item(i);
				Element e = (Element) node;
				if (e.getAttribute("examid").equals(examid.trim())) {
					// 获取该节点的信息
					student = new Student();
					student.setExamid(examid);
					student.setIdcard(e.getAttribute("idcard"));
					student.setName(e.getElementsByTagName("name").item(0).getTextContent());
					student.setLocation(e.getElementsByTagName("location").item(0).getTextContent());
					student.setGrade(Float.parseFloat(e.getElementsByTagName("grade").item(0).getTextContent()));
				}
			}
			
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		
		return student;
	}
}

cn.example.test包

package cn.example.test;

import cn.example.dao.StudentDao;
import cn.example.domain.Student;

public class StudentDaoTest {
	public static void main(String[] args) {
		Student student = new Student();
		student.setName("Tam");
		student.setExamid("12312");
		student.setGrade(100f);
		student.setIdcard("123121");
		student.setLocation("Hongkong");
		
		StudentDao dao = new StudentDao();
		dao.addStudent(student);
		
//		dao.removeStudent("Tam");
		
		Student s = dao.queryStudent("12312");
		System.out.println(s);
	}
}

cn.example.ui包

package cn.example.ui;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import cn.example.dao.StudentDao;
import cn.example.domain.Student;

/**
 * 用户操作界面
 */
public class Main {
	public static void main(String[] args) {
		StudentDao dao = new StudentDao();
		// 打印操作提示
		System.out.println("添加用户:(a)\t删除用户:(b)\t查询成绩:(c)");
		System.out.println("请输入操作类型:");
		// 接收用户的操作
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(
					System.in));
			String operation = br.readLine();
			if ("a".equals(operation)) {
				// 添加操作
				System.out.println("请输入学生姓名:");
				String name = br.readLine();
				System.out.println("请输入学生准考证号:");
				String examid = br.readLine();
				System.out.println("请输入学生身份证号:");
				String idcard = br.readLine();
				System.out.println("请输入学生所在地:");
				String location = br.readLine();
				System.out.println("请输入学生成绩:");
				String grade = br.readLine();
				Student student = new Student();
				student.setExamid(examid);
				student.setIdcard(idcard);
				student.setName(name);
				student.setGrade(Float.parseFloat(grade));
				student.setLocation(location);
				boolean result = dao.addStudent(student);
				if (result) {
					System.out.println("----添加数据成功-----");
				} else {
					System.out.println("----添加数据失败-----");
				}
			} else if ("b".equals(operation)) {
				// 删除操作
				System.out.println("请输入删除的学生的姓名:");
				String name = br.readLine();
				boolean result = dao.removeStudent(name);
				if (result) {
					System.out.println("----已成功删除学生信息-----");
				} else {
					System.out.println("----删除学生信息失败-----");
				}

			} else if ("c".equals(operation)) {
				// 查询操作
				System.out.println("请输入查询的学生的准考证号");
				String examid = br.readLine();
				Student student = dao.queryStudent(examid);
				if (student == null) {
					System.out.println("学生不存在");
				}else{
					System.out.println(student);
				}
			} else {
				System.out.println("输入错误");
			}
		} catch (Exception e) {
			System.out.println("输入错误");
		}

	}
}

更新XML文档

l  javax.xml.transform包中的Transformer类用于把代表XML文件的Document对象转换为某种格式后进行输出,例如把xml文件应用样式表后转成一个html文档。利用这个对象,当然也可以把Document对象又重新写入到一个XML文件中。

l  Transformer类通过transform方法完成转换操作,该方法接收一个源和一个目的地。我们可以通过:

•      javax.xml.transform.dom.DOMSource类来关联要转换的document对象,

•      javax.xml.transform.stream.StreamResult对象来表示数据的目的地。

l   Transformer对象通过TransformerFactory获得。


SAX解析

l  在使用DOM 解析XML文档时,需要读取整个XML 文档,在内存中构架代表整个DOM 树的Doucment对象,从而再对XML文档进行操作。此种情况下,如果XML 文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出。

l  SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会文档进行操作。


SAX解析

l  SAX采用事件处理的方式解析XML文件,利用SAX 解析XML文档,涉及两个部分:解析器和事件处理器:

•      解析器可以使用JAXPAPI创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。

•      解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。

•      事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。

SAX解析



SAX方式解析XML文档

l   使用SAXParserFactory创建SAX解析工厂

SAXParserFactoryspf = SAXParserFactory.newInstance();

l   通过SAX解析工厂得到解析器对象        

SAXParsersp = spf.newSAXParser();

l   通过解析器对象得到一个XML的读取器

XMLReaderxmlReader = sp.getXMLReader();

l   设置读取器的事件处理器      

xmlReader.setContentHandler(newBookParserHandler());

l   解析xml文件

xmlReader.parse("book.xml");

SAX方式解析XML文档

l   SAX解析编程


DOM4J解析XML文档

l  Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4jAPI相对要复杂一些,但它提供了比JDOM更好的灵活性。

l  Dom4j是一个非常优秀的JavaXML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j

l  使用Dom4j开发,需下载dom4j相应的jar文件。

 

Document对象

l  DOM4j中,获得Document对象的方式有三种:

    1.读取XML文件,获得document对象            

                   SAXReaderreader = new SAXReader();
 
            Document   document =reader.read(new File("input.xml"));

    2.解析XML形式的文本,得到document对象.

                  String text = "<members></members>";
 
            Document document = DocumentHelper.parseText(text);

    3.主动创建document对象.

                 Document document = DocumentHelper.createDocument();
 
           //创建根节点

                 Element root =document.addElement("members");


节点对象

l  1.获取文档的根节点.

      Element root = document.getRootElement();

l  2.取得某个节点的子节点.

       Element element=node.element(书名");

l   3.取得节点的文字

      Stringtext=node.getText();

l  4.取得某节点下所有名为“member的子节点,并进行遍历.
 
List nodes =rootElm.elements("member");
 
  for (Iterator it = nodes.iterator();it.hasNext();) {
    Element elm = (Element) it.next();
 
   //do something
 
}

l  5.对某节点下的所有子节点进行遍历.
  
 for(Iteratorit=root.elementIterator();it.hasNext();){
 
      Elementelement = (Element) it.next();
 
      //do something
 
   }

l  6.在某节点下添加子节点.
Element ageElm = newMemberElm.addElement("age");

l  7.设置节点文字.
 
element.setText("29");

l  8.删除某节点.
//childElm
是待删除的节点,parentElm是其父节点

    parentElm.remove(childElm);

l  9.添加一个CDATA节点.
Element contentElm = infoElm.addElement("content");
contentElm.addCDATA(diary.getContent());


节点对象属性 

l  1.取得某节点下的某属性
 
   Elementroot=document.getRootElement();    
 
   //属性名name

         Attributeattribute=root.attribute("size");

l  2.取得属性的文字
 
   Stringtext=attribute.getText();

 

l   3.删除某属性
 
Attributeattribute=root.attribute("size");
 
root.remove(attribute);

节点对象属性 

l  3.遍历某节点的所有属性
 
  Elementroot=document.getRootElement();    
 
 for(Iteratorit=root.attributeIterator();it.hasNext();){
 
        Attributeattribute = (Attribute) it.next();
 
        Stringtext=attribute.getText();
 
        System.out.println(text);
 
   }

 

l  4.设置某节点的属性和文字.
  
newMemberElm.addAttribute("name", "sitinspring");

 

l  5.设置属性的文字
  
Attributeattribute=root.attribute("name");
 
  attribute.setText("sitinspring");


将文档写入XML文件.

l  1.文档中全为英文,不设置编码,直接写入的形式.
 
XMLWriter writer = newXMLWriter(new FileWriter("output.xml"));
  writer.write(document);
  writer.close();

 

l  2.文档中含有中文,设置编码格式写入的形式.
OutputFormat format = OutputFormat.createPrettyPrint();
//
指定XML编码                 

format.setEncoding("GBK");

 XMLWriter writer = new XMLWriter(new FileOutputStream ("output.xml"),format);
writer.write(document);
writer.close();


Dom4j在指定位置插入节点

l  1.得到插入位置的节点列表(list

l  2.调用list.add(index,elemnent),由index决定element的插入位置。

l  Element元素可以通过DocumentHelper对象得到。示例代码:

 

Elementaaa = DocumentHelper.createElement("aaa");

aaa.setText("aaa");

 

Listlist = root.element("").elements();

list.add(1,aaa);

//更新document


字符串与XML的转换

l  1.将字符串转化为XML
 

     String text = "<members><member>sitinspring</member></members>";
Document document = DocumentHelper.parseText(text);

 

l  2.将文档或节点的XML转化为字符串.

     SAXReader reader = new SAXReader();
Document   document =reader.read(new File("input.xml"));            
Element root=document.getRootElement();
    

            
String docXmlText=document.asXML();

StringrootXmlText=root.asXML();
Element memberElm=root.element("member");
String memberXmlText=memberElm.asXML();


XML约束之Schema

XML Schema

l  XML Schema 也是一种用于定义和描述XML 文档结构与内容的模式语言,其出现是为了克服DTD 的局限性

l  XML Schema VS DTD

•             XML Schema符合XML语法结构。

•             DOMSAXXMLAPI很容易解析出XML Schema文档中的内容。

•             XML Schema名称空间支持得非常好。

•             XML SchemaXMLDTD支持更多的数据类型,并支持用户自定义新的数据类型。

•             XML Schema定义约束的能力非常强大,可以对XML实例文档作出细致的语义限制。

•             XML Schema不能像DTD一样定义实体,比DTD更复杂,但XmlSchema现在已是w3c组织的标准,它正逐步取代DTD 


Schema约束快速入门


Schema入门案例

<?xmlversion="1.0" encoding="UTF-8" ?>

<xs:schemaxmlns:xs=http://www.w3.org/2001/XMLSchema//标准的名称空间

                              targetNamespace=http://www.itcast.cn //将该schema文档绑定到http://www.itcast.cn名称空间

                              elementFormDefault="qualified">

    <xs:element name='书架' >

      <xs:complexType>

        <xs:sequence maxOccurs='unbounded' >

           <xs:element name='书' >

              <xs:complexType>

                 <xs:sequence>

                    <xs:elementname='书名' type='xs:string' />

                    <xs:element name='作者' type='xs:string' />

                    <xs:element name='售价' type='xs:string' />

                 </xs:sequence>

              </xs:complexType>

           </xs:element>

        </xs:sequence>

      </xs:complexType>

    </xs:element>

</xs:schema>

Schema入门案例

<?xmlversion="1.0" encoding="UTF-8"?>

 

<itcast:书架 xmlns:itcast="http://www.itcast.cn"

           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

           xsi:schemaLocation=“http://www.itcast.cnbook.xsd">

 

    <itcast:>

      <itcast:书名>JavaScript网页开发</itcast:书名>

      <itcast:作者>张孝祥</itcast:作者>

      <itcast:售价>28.00</itcast:售价>

    </itcast:>

</itcast:书架>

 

名称空间的概念

l  XML Schema中,每个约束模式文档都可以被赋以一个唯一的名称空间,名称空间用一个唯一的URIUniformResource Identifier,统一资源标识符)表示。Xml文件中书写标签时,可以通过名称空间声明(xmlns),来声明当前编写的标签来自哪个Schema约束文档。如:

    <itcast:书架 xmlns:itcast=“http://www.itcast.cn”>

      <itcast:>……</itcast:>

    </itcast:书架>

        此处使用itcast来指向声明的名称,以便于后面对名称空间的引用。

l  注意:名称空间的名字语法容易让人混淆,尽管以http://开始,那个URL 并不指向一个包含模式定义的文件。事实上,这个URLhttp://www.itcast.cn根本没有指向任何文件,只是一个分配的名字。

 

使用名称空间引入Schema

l  为了在一个XML文档中声明它所遵循的Schema文件的具体位置,通常需要在Xml文档中的根结点中使用schemaLocation属性来指定,例如:

    <itcast:书架 xmlns:itcast="http://www.itcast.cn"

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xsi:schemaLocation=“http://www.itcast.cnbook.xsd">

l  schemaLocation此属性有两个值。第一个值是需要使用的命名空间。第二个值是供命名空间使用的XML schema 的位置,两者之间用空格分隔。

l  注意,在使用schemaLocation属性时,也需要指定该属性来自哪里。


使用默认名称空间

l   基本格式:

    xmlns="URI" 

l   举例:

    <书架 xmlns="http://www.it315.org/xmlbook/schema"

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xsi:schemaLocation=“http://www.itcast.cnbook.xsd">

      <>

       <书名>JavaScript网页开发</书名>

       <作者>张孝祥</作者>

       <售价>28.00</售价>

      </>

    <书架>

 

使用名称空间引入多个XML Schema文档


不使用名称空间引入XML Schema文档


XML Schema文档中声明名称空间


Schema语法

l   参看w3c文档



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值