00 03Java Web开发之Schema:基于XML的DTD替代者

1 Schema的介绍

dtd语法:<!ELEMENT 元素名称 约束>

schema符合xml语法,符合xml语法。

一个xml中可以有多个schema,只能有一个dtd。多个schema使用名称空间区分(类似于Java包名)。

dtd里面只有PCDATA类型,但是在schema里面可以支持更多的数据类型
|——比如年龄,只能是整数,在schema可以直接定义一个整数类型
由此可以发现schema语法更加严格。

schema语法更加复杂,schema目前不能代替dtd,两者共存。

2 Schema的开发过程

创建一个schema文件,后缀名是.xsd
|——根节点 <schema>
|——在schema元素里面
|——(1)属性:xmlns="http://www.w3.org/2001/XMLSchema",表示当前xml文件是一个约束文件
|——(2)属性:targetNamespace="http://www.itcast.cn/20151111",使用schema约束文件,直接通过这个地址引入约束文件
|——(3)属性:elementFormDefault="qualified"
步骤:
|——(1)看xml中有多少个元素,就定义多少个<element>
|——(2)看简单元素和复杂元素。如果是复杂元素,要用<complexType><sequence>元素的定义,示例如下:

<complexType>
    <sequence>
        子元素
    <sequencs>
</complexType>

如果是简单元素,直接使用<element name="" type=""></element>格式定义,属性name指被约束文件中元素名称,type指数据类型。

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://www.example.org/person" 
xmlns:tns="http://www.example.org/person" 
elementFormDefault="qualified">
<element name="person">
    <complexType>
        <sequence>
            <element name="name" type="string"></element>
            <element name="age" type="int" />
        </sequence>
    </complexType>
</element>

</schema>

|——(3)在被约束文件里面引入约束文件,其中xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"属性表示此文件就是被约束文件,xmlns="http://www.itcast.cn/20151111"属性是约束文件里的targetNamespace属性,xsi:schemaLocation="http://www.itcast.cn/20151111 person.xsd"属性指被约束文件位置(格式:targetNamespace 空格 约束文件地址路径

<?xml version="1.0" encoding="UTF-8"?>
<person xmlns="http://www.example.org/person"
xmlns:per="http://www.w3.org/2001/XMLSchema-instance"
per:schemaLocation="http://www.example.org/person person.xsd"
>
    <name>lks</name>
    <age>23</age>
</person>

3 Schema约束API查看

(1)<sequence>:表示元素出现顺序
(2)<all>:表示元素只能出现一次
(3)<choice>:表示元素只能出现其中一个
(4)maxOccurs="unbounded":元素属性,表示元素的出现的次数
(4)<any></any>:表示任意元素

可以约束属性
(1)写在复杂元素里面;
(2)写在</complex>之前,
(3)语法:<attribute name="" type="" use=""></attribute>,属性name指要约束的属性名,type指属性类型,use指属性是否必须出现(required指必须出现)。

复杂的schema约束
(1)引入多个schema文件,可以给每个文件起个别名。
(2)多余多个schema文件中对元素的约束,可以使用别名:元素来定义。

4 sax解析的过程

解析xml有两种技术:dom和sax。

dom技术步骤:
(1)根据xml的层级结构在内存中分配一个树形结构
(2)把xml中的标签、属性、文本都封装成对象

sax方式:事件驱动,边读边解析。

在java.xml.parsers包里面:
(1)public abstract class SAXParser extends Object: 此类实例可以从SAXParserFactory.newSAXParser()方法获得。使用public void parse​(File f, DefaultHandler dh) throws SAXException, IOException方法,第一个参数是xml路径,第二个参数是事件处理器。
(2)public abstract class SAXParserFactory extends Object:实例通过newInsance()获得。

sax执行过程:

5 使用Jaxp的sax方式操作

sax方式不能实现增删改操作,只能实现查询操作

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<person>
    <p1>
        <name>lks</name>
        <age>23</age>
    </p1>
    <p1>
        <name>hhy</name>
        <age>20</age>
    </p1>
</person>
public class JaxpTest {

	public static void main(String []args) throws Exception{
		SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
		SAXParser saxParser = saxParserFactory.newSAXParser();
		saxParser.parse("src/dtdlearn/mydtd00/person.xml", new MyDefaultHandler());
	}
}

打印出整个文档。
(1)创建解析器工厂
(2)创建解析器
(3)执行parse方法
(4)自己创建一个类,继承DefaultHandler
(5)重写类里面的三个方法

class MyDefaultHandler extends DefaultHandler{

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		// TODO Auto-generated method stub
		System.out.print("<" + qName + ">");
	}

	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		// TODO Auto-generated method stub
		System.out.print("<\\" + qName + ">");
	}

	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		// TODO Auto-generated method stub
		System.out.print(new String(ch, start, length));
	}
	
}

获取所有name元素的值。
(1)定义成员变量flag=false
(2)判断开始方法是否是name元素,如果是name元素,那么flag=true
(3)判断flag是否为true,如果是,就打印出character()方法内容
(4)当执行到name结束的时候,置flag为false

class MyDefaultHandler1 extends MyDefaultHandler{
	private boolean flag = false;

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		// TODO Auto-generated method stub
		if( "name".equals(qName)) {
			flag = true;
		}
	}
	
	

	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		// TODO Auto-generated method stub
		if(flag== true) {
			super.characters(ch, start, length);
			System.out.println();
		}
	}



	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		// TODO Auto-generated method stub
		if( "name".equals(qName)) {
			flag = false;
		}
	}
} 

获取第一个name元素的值。
(1)定义成员变量 idx = 1
(2)判断开始方法是否为name,如果是,继续判断idx是否为1,如果是,那么flag=true
(3)判断flag是否为true,如果是,就打印内容
(4)当执行到name元素结束,flag=false

class MyDefaultHandler2 extends MyDefaultHandler1{
	private int idx = 1;

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		// TODO Auto-generated method stub
		super.startElement(uri, localName, qName, attributes);
	}

	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		// TODO Auto-generated method stub
		if( idx == 1) {
			super.characters(ch, start, length);
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		// TODO Auto-generated method stub
		super.endElement(uri, localName, qName);
		if("name".equals(qName)) {
			idx++;
		}
	}
}
发布了77 篇原创文章 · 获赞 11 · 访问量 2634

猜你喜欢

转载自blog.csdn.net/weixin_43762330/article/details/104532645