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文档



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目 录 译者序 作者简介 前言 第1章 XML简介 1.1 标记语言 1.2 XML的起源和目的 1.3 Web体系结构:过去与未来 1.3.1 传统Web体系结构 1.3.2 XML下的Web体系结构 1.4 XML基本特征 1.5 词汇表 1.5.1 科学词汇表 1.5.2 商业词汇表 1.5.3 法律词汇表 1.5.4 医学词汇表 1.5.5 计算机词汇表 1.6 XML技术的主要特性 1.6.1 格式正规的XML 1.6.2 文档类型定义 1.6.3 数据建模 1.6.4 文档对象模型 1.6.5 XML 简单API 1.6.6 命名空间和模式 1.6.7 链接和查询 1.6.8 转换XML 1.6.9 XML和数据库 1.6.10 服务器到服务器 1.6.11 电子商务与XML 1.6.12 使用样式 1.6.13 无线应用程序协议和WML 1.7 XML的应用程序举例 1.8 小结 第2章 XML语法 2.1 标记语法 2.1.1 字符 2.1.2 命名 2.2 文档部分 2.3 元素 2.3.1 起始标记 2.3.2 结束标记 2.3.3 空元素标记 2.3.4 标记:一个简单的例子 2.3.5 文档元素 2.3.6 子元素 2.3.7 元素嵌套 2.3.8 字符串 2.4 字符数据 2.5 属性 2.5.1 特殊属性 2.5.2 空白 2.5.3 行尾的处理 2.6 字符引用和实体引用 2.6.1 字符引用 2.6.2 实体引用 2.7 处理指令 2.8 注释 2.9 CDATA部分 2.10 文档结构 2.10.1 序言 2.10.2 尾声 2.11 XML语法小结 2.12 格式正规的文档 2.13 解析器 2.13.1 事件驱动的解析器 2.13.2 基于树的解析器 2.13.3 解析器基准测试 2.14 书籍目录应用程序 2.15 小结 第3章 文档类型定义 3.1 为何需要正式的结构 3.1.1 文档域 3.1.2 验证文档的有效性 3.2 编写DTD:通用原则 3.2.1 将DTD与XML文档相关联 3.2.2 基本标记声明 3.3 正式的DTD结构 3.3.1 实体 3.3.2 元素 3.3.3 属性 3.3.4 条件部分 3.4 DTD的缺点 3.5 用于图书目录问题的DTD 3.5.1 图书目录问题的正式定义 3.5.2 对象关系问题 3.5.3 进一步讨论 3.6 小结 第4章 数据建模与XML 4.1 信息建模 4.1.1 静态模型和动态模型 4.1.2 文档和数据 4.1.3 从何处开始 4.1.4 静态信息模型 4.1.5 动态建模:对数据进行哪些处理? 4.2 设计XML文档 4.2.1 XML的两种角色 4.2.2 将信息模型映射到XML 4.3 模式语言和表示法 4.3.1 模式的作用 4.3.2 将DTD作为模式 4.3.3 XML模式建议 4.4 小结 第5章 文档对象模型 5.1 什么是文档对象模型 5.1.1 XML文档结构 5.1.2 为何使用DOM 5.1.3 DOM规范 5.1.4 现实世界中的DOM 5.1.5 特殊的XML DOM实例— HTML DOM 5.2 使用DOM 5.2.1 DOM API 5.2.2 客户端和服务器端 5.2.3 DOM在出版过程中的应用 5.3 使用DOM和XML的应用实例 5.3.1 简单的客户端实例 5.3.2 更复杂的编程实例 5.4 DOM和XML的未来 5.4.1 W3C的工作 5.4.2 应用 5.4.3 数据库、模式和DOM 5.5 小结 第6章 SAX 1.0: XML简易API 6.1 事件驱动接口 6.2 SAX的由来 6.3 SAX的高级特性 6.3.1 可选择的源输入 6.3.2 处理外部实体 6.3.3 选择解析器 6.4 一些SAX设计模式 6.5 SAX 2.0 6.5.1 可配置的接口 6.5.2 核心的特性和属性 6.6 小结 第7章 命名空间和模式 7.1 混合词汇表 7.1.1 分解问题 7.1.2 重用 7.1.3 二义性与名称冲突 7.2 命名空间 7.3 定义和声明命名空间 7.3.1 声明一个命名空间 7.3.2 限定名 7.3.3 范围 7.4 在格式正规的书籍里使用命名空间 实例 7.5 模式 7.5.1 与DTD有关的问题 7.5.2 一个对创建模式的帮助 7.6 W3C在XML 模式方面的工作 7.6.1 DTD与XML 模式的比较 7.6.2 结构 7.6.3 数据类型 7.7 简化了的XML Data 7.7.1 MSXML对命名空间和模式的支持 7.7.2 数据类型 7.8 图书目录中的变化 7.8.1 为什么烦恼 7.8.2 重铸DTD 7.8.3 模式协调 7.9 小结 第8章 链接和查询 8.1 XML 信息集合 8.1.1 信息类型 8.1.2 信息集合的重要性 8.1.3 小结 8.2 链接 8.2.1 什么是链接? 8.2.2 W3C规范:XLink 8.3 Xpointer 8.3.1 HTML指针 8.3.2 Xpointer 规范 8.4 W3C Xpath推荐标准 8.4.1 Location Step 8.4.2 XPointer对XPath的扩展 8.4.3 Xpointer错误 8.4.4 小结 8.5 XML片段交换 8.5.1 什么是文档片段 8.5.2 文档片段的一些用途 8.5.3 问题:Bare文档片段并不总 是充分的 8.5.4 解决办法:环境信息 8.5.5 回顾实例 8.5.6 如何传输片段 8.5.7 小结 8.6 查询 8.6.1 什么是查询语言 8.6.2 关系型数据库和XML文档之间的区别 8.6.3 XML查询语言的发展历史 8.6.4 使用Xpath和XSLT查询XML文档 8.6.5 查询语言展望 8.7 小结 第9章 转换 XML 9.1 为什么转换 XML 9.1.1 在不同词汇表之间转换 9.1.2 动态转换 9.1.3 不同的浏览器 9.2 XSL 9.3 XSLT 样式表结构 9.3.1 创建模板 9.3.2 处理空白 9.3.3 输出格式 9.3.4 合并样式表 9.3.5 嵌入样式表 9.4 使用XSLT的例子 9.4.1 结构的转换 9.4.2 循环 9.4.3 排序 9.4.4 条件处理 9.4.5 名称模板 9.4.6 编号方式 9.4.7 拷贝 9.5 使用DOM进行XML文档的转换

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值