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++;
}
}
}