1 : 什么是Schema?
用来定义XML文件,并利用该定义验证XML文件是否符合要求的一种技术。
2: Schema与DTD的区别:
(1):XML Schema是XML文档,而DTD有自己的特殊语法。这样,只需要懂得XML的语法规则就可以编写Schema,无须学习其他的语法规则;
XML文件与XML Schema文件可以用相同的解析器进行解
析,无须两套解析器;XML Schema有强大、易用的扩展性。
(2):XML Schema利用命名空间将文档中的特殊的节点与Schema说明相联系,
一个XML文件可以有多个Schema,而对于DTD一个XML只能有一个相对应的DTD。
(3):XML Schema内容模型是开发的,可以随意扩充,而DTD则无法解析扩充的内容。
(4):DTD只能把内容类型定义为一个字符串,而XML Schema允许把内容类型定义为整形、浮点型、布尔型等等,而无须重定义。
综上,XML Schema较DTD有着优势,所以尽量把XML Schema作为首选为佳。
3: 简单语法举例
6种最常用的基本类型 String decimal(小数) integer date time boolean
元素定义:<!xs:element name="" type="" default=""/fixed="">
属性定义:<!xs:attribute name="" type="" default=""/fixed=""/use="required">
注意:Schema中,属性声明于元素声明的唯一区别就是"use"用于定义属性是否出现在实例文档中。
required(必须存在) optional(可存在也可不存在) prohibited(必须不存在)
元素定义分两种: simpleType与complexType
simpleType:没有子元素的 只包含自己的值 定义了一个简单的元素或者属性
complexType:由多个简单元素组成 可以层层嵌套
1:什么叫解析器:一些用来对XML文件进行解析的程序。
2:解析方法举例:XML最基本的解析方式有两种,分别是DOM和SAX
3:下面分别对两种解析方式重点介绍:
SAX--Simple API for XML API中 org.xml.sax
基于事件模型的处理方式,解释器发生事件通知应用程序
当您使用 SAX 解析器来解析 XML 文档时,解析器在文档的不同处将产生事件。
由您来决定对每个事件如何处理。
SAX 解析器会在以下情况下产生事件:在文档开始和结束时,在一个元素开始和结束时,或者它在一个元素中找到字符时,以及其它若干点。
您可编写 Java 代码来处理每个事件,以及如何处理从解析器获得的信息。
如何使用SAX解析:
1)解析
String xmlURI = "c:/test.xml";
String vendorParserClass = "org.apache.xerces.parsers.SAXParser";
XMLReaer reader = XMLReaderFactory.createXMLReader(vendorParserClass);
InputSource inputSource = new InputSource(xmlURI);
reader.parse(inputSource);
这样一个xml文档解析过程就完成了。因为SAX是采用时间处理机制来解析XML
文档的,在解析过程中会触发一些事件,也就是执行特定的方法,你可以实现
这些方法,就可以通过解析xml来做一些事情了
2)处理
SAX2.0定义的核心处理接口一共有
org.xml.sax.ContentHandler
org.xml.sax.ErrorHandler
org.xml.sax.DTDHandler
org.xml.sax.EntityResolver
这些接口是通过
org.xml.sax.XMLReader的setContentHandler(),setEroorHandler(),
setDTDHandler(),setEntityHandler()注册到解析器,这里面最重要的是
org.xml.sax.ContentHandler接口,它具体如下
public interface ContentHandler{
public void setDocumentLocator(Locator locator);
public void startDocument() throws SAXException;
public void endDocument() throws SAXException;
public void startPrefixMapping(String prefix,String uri)
throws SAXException;
public void endPrefixMapping(String prifix)
throws SAXException;
public void startElement(String namespaceURI,String localName,
String qName,Attributes atts) throws SAXException;
public void endElement(String namespaceURI,String localName,
String qName) throws SAXException;
public void characters(char ch[],int start,int length)
throws SAXException;
public void ignorableWhitespace(char ch[],int start,int length)
throws SAXException;
public void processingInstruction(String target,String data)
throws SAXException;
public void skippedEntity(String name)
throws SAXException;
}
通过setContentHandler()将你实现的ContentHandler注册给XMLReader之后,
在解析过程中,系统根据各种条件执行接口中的方法,下面简单说明一下
1)文档定位器
private Locator locator;
public void setDocumentLocator(Locator locator){
this.locator = locator;
}
通常情况下,你只要如此实现就可以了,这个主要是得到当前解析的位置,
通过得到的locator,你可以使用它的getLineNumber(),getColumnName()等
方法,可以得到文档当前的位置,但要注意的是,这个locator不能保存,只
针对当前的解析有效
2)文档的开头和结尾
public void startDocument() throws SAXException{
//解析过程中仅位于setDocumentLocator()方法后调用
}
public void endDocument() throws SAXException{
//解析过程中最后调用
}
大多数情况下你可以不用理他们,只要写个空方法就可以了
3)名字空间的开始和结束
public void startPrefixMapping(String prefix,String uri)
throws SAXException{
}
public void endPrefixMapping(String prifix)
throws SAXException{
}
4)元素的开始和结束
public void startElement(String namespaceURI,String localName,
String qName,Attributes atts) throws SAXException{
}
public void endElement(String namespaceURI,String localName,
String qName) throws SAXException{
}
5)元素的数据
public void characters(char ch[],int start,int length)
throws SAXException{
String s = new String(ch,start,length);
}
这个是得到当前的元素的文本数据
6)可以忽略的空白
public void ignorableWhitespace(char ch[],int start,int length)
throws SAXException{
}
7)实体
public void skippedEntity(String name)
throws SAXException{
}
8)指令处理
public void processingInstruction(String target,String data)
throws SAXException{
}
-----------------------------------------
DOM----API中的org.w3c.dom
基于树和节点的文档对象模型
一种基于对象的API,
它把XML的内容加载到内存中,生成一个与XML文档对应的对象模型。
解析完成时,内存中会生成与XML文档结构对应的DOM对象树。我们根据树的结 构,以节点形式对文档进行操作。
使用DOM解析方法:
(1)得到DOM解析器的工厂实例
DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
得到javax.xml.parsers.DocumentBuilderFactory;类的实例就是我们要的解析器工厂
(2)从DOM工厂获得DOM解析器
DocumentBuilder dombuilder=domfac.newDocumentBuilder();
通过javax.xml.parsers.DocumentBuilderFactory实例的静态方法newDocumentBuilder()得到DOM解析器
(3)把要解析的XML文档转化为输入流,以便DOM解析器解析它
InputStream is=new FileInputStream("/home/asd0809/abc.xml");
InputStream是一个接口。
(4)解析XML文档的输入流,得到一个Document
Document doc=dombuilder.parse(is);
由XML文档的输入流得到一个org.w3c.dom.Document对象,以后的处理都是对Document对象进行的
(5)得到XML文档的根节点
Element root=doc.getDocumentElement();
在DOM中只有根节点是一个org.w3c.dom.Element对象。
(6)得到节点的子节点
NodeList books=root.getChildNodes();
for(int i=0;i<books.getLength();i++){
Node book=books.item(i);
}
这是用一个org.w3c.dom.NodeList接口来存放它所有子节点的,还有一种轮循子节点的方法,后面有介绍
(7)取得节点的属性值
String email=book.getAttributes().getNamedItem("email").getNodeValue();
System.out.println(email);
注意,节点的属性也是它的子节点。它的节点类型也是Node.ELEMENT_NODE
(8)轮循子节点
for(Node node=book.getFirstChild();node!=null;node=node.getNextSibling()){
if(node.getNodeType()==Node.ELEMENT_NODE){
if(node.getNodeName().equals("name")){
String name=node.getNodeValue();
String name1=node.getFirstChild().getNodeValue();
System.out.println(name);
System.out.println(name1);
}
if(node.getNodeName().equals("price")){
String price=node.getFirstChild().getNodeValue();
System.out.println(price);
}
}
----------------------------------------------------------------
4:其它关于解析问题
何时使用 SAX?何时使用 DOM?
文本大用SAX 消耗内存大 ; 如果要来回读 要用DOM
JAXP-------javax.xml.parser(sun公司的API 包含了上面两种API 是类不是接口 只是一个入口 )-----统一接口,默认解析器
其他公司的工具包
JDOM(基于DOM)
Dom4j(基于DOM)最流行
Apache Xerces(基于SAX)