1 : 什么是Schema?
用來定義XML文件,并利用該定義驗(yàn)證XML文件是否符合要求的一種技術(shù)。
2: Schema與DTD的區(qū)別:
(1):XML Schema是XML文檔,而DTD有自己的特殊語法。這樣,只需要懂得XML的語法規(guī)則就可以編寫Schema,無須學(xué)習(xí)其他的語法規(guī)則;
XML文件與XML Schema文件可以用相同的解析器進(jìn)行解
析,無須兩套解析器;XML Schema有強(qiáng)大、易用的擴(kuò)展性。
(2):XML Schema利用命名空間將文檔中的特殊的節(jié)點(diǎn)與Schema說明相聯(lián)系,
一個XML文件可以有多個Schema,而對于DTD一個XML只能有一個相對應(yīng)的DTD。
(3):XML Schema內(nèi)容模型是開發(fā)的,可以隨意擴(kuò)充,而DTD則無法解析擴(kuò)充的內(nèi)容。
(4):DTD只能把內(nèi)容類型定義為一個字符串,而XML Schema允許把內(nèi)容類型定義為整形、浮點(diǎn)型、布爾型等等,而無須重定義。
綜上,XML Schema較DTD有著優(yōu)勢,所以盡量把XML Schema作為首選為佳。
3: 簡單語法舉例
6種最常用的基本類型 String decimal(小數(shù)) integer date time boolean
元素定義:<!xs:element name="" type="" default=""/fixed="">
屬性定義:<!xs:attribute name="" type="" default=""/fixed=""/use="required">
注意:Schema中,屬性聲明于元素聲明的唯一區(qū)別就是"use"用于定義屬性是否出現(xiàn)在實(shí)例文檔中。
required(必須存在) optional(可存在也可不存在) prohibited(必須不存在)
元素定義分兩種: simpleType與complexType
simpleType:沒有子元素的 只包含自己的值 定義了一個簡單的元素或者屬性
complexType:由多個簡單元素組成 可以層層嵌套
1:什么叫解析器:一些用來對XML文件進(jìn)行解析的程序。
2:解析方法舉例:XML最基本的解析方式有兩種,分別是DOM和SAX
3:下面分別對兩種解析方式重點(diǎn)介紹:
SAX--Simple API for XML API中 org.xml.sax
基于事件模型的處理方式,解釋器發(fā)生事件通知應(yīng)用程序
當(dāng)您使用 SAX 解析器來解析 XML 文檔時,解析器在文檔的不同處將產(chǎn)生事件。
由您來決定對每個事件如何處理。
SAX 解析器會在以下情況下產(chǎn)生事件:在文檔開始和結(jié)束時,在一個元素開始和結(jié)束時,或者它在一個元素中找到字符時,以及其它若干點(diǎn)。
您可編寫 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文檔解析過程就完成了。因?yàn)镾AX是采用時間處理機(jī)制來解析XML
文檔的,在解析過程中會觸發(fā)一些事件,也就是執(zhí)行特定的方法,你可以實(shí)現(xiàn)
這些方法,就可以通過解析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()將你實(shí)現(xiàn)的ContentHandler注冊給XMLReader之后,
在解析過程中,系統(tǒng)根據(jù)各種條件執(zhí)行接口中的方法,下面簡單說明一下
1)文檔定位器
private Locator locator;
public void setDocumentLocator(Locator locator){
this.locator = locator;
}
通常情況下,你只要如此實(shí)現(xiàn)就可以了,這個主要是得到當(dāng)前解析的位置,
通過得到的locator,你可以使用它的getLineNumber(),getColumnName()等
方法,可以得到文檔當(dāng)前的位置,但要注意的是,這個locator不能保存,只
針對當(dāng)前的解析有效
2)文檔的開頭和結(jié)尾
public void startDocument() throws SAXException{
//解析過程中僅位于setDocumentLocator()方法后調(diào)用
}
public void endDocument() throws SAXException{
//解析過程中最后調(diào)用
}
大多數(shù)情況下你可以不用理他們,只要寫個空方法就可以了
3)名字空間的開始和結(jié)束
public void startPrefixMapping(String prefix,String uri)
throws SAXException{
}
public void endPrefixMapping(String prifix)
throws SAXException{
}
4)元素的開始和結(jié)束
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)元素的數(shù)據(jù)
public void characters(char ch[],int start,int length)
throws SAXException{
String s = new String(ch,start,length);
}
這個是得到當(dāng)前的元素的文本數(shù)據(jù)
6)可以忽略的空白
public void ignorableWhitespace(char ch[],int start,int length)
throws SAXException{
}
7)實(shí)體
public void skippedEntity(String name)
throws SAXException{
}
8)指令處理
public void processingInstruction(String target,String data)
throws SAXException{
}
-----------------------------------------
DOM----API中的org.w3c.dom
基于樹和節(jié)點(diǎn)的文檔對象模型
一種基于對象的API,
它把XML的內(nèi)容加載到內(nèi)存中,生成一個與XML文檔對應(yīng)的對象模型。
解析完成時,內(nèi)存中會生成與XML文檔結(jié)構(gòu)對應(yīng)的DOM對象樹。我們根據(jù)樹的結(jié) 構(gòu),以節(jié)點(diǎn)形式對文檔進(jìn)行操作。
使用DOM解析方法:
(1)得到DOM解析器的工廠實(shí)例
DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
得到j(luò)avax.xml.parsers.DocumentBuilderFactory;類的實(shí)例就是我們要的解析器工廠
(2)從DOM工廠獲得DOM解析器
DocumentBuilder dombuilder=domfac.newDocumentBuilder();
通過javax.xml.parsers.DocumentBuilderFactory實(shí)例的靜態(tài)方法newDocumentBuilder()得到DOM解析器
(3)把要解析的XML文檔轉(zhuǎn)化為輸入流,以便DOM解析器解析它
InputStream is=new FileInputStream("/home/asd0809/abc.xml");
InputStream是一個接口。
(4)解析XML文檔的輸入流,得到一個Document
Document doc=dombuilder.parse(is);
由XML文檔的輸入流得到一個org.w3c.dom.Document對象,以后的處理都是對Document對象進(jìn)行的
(5)得到XML文檔的根節(jié)點(diǎn)
Element root=doc.getDocumentElement();
在DOM中只有根節(jié)點(diǎn)是一個org.w3c.dom.Element對象。
(6)得到節(jié)點(diǎn)的子節(jié)點(diǎn)
NodeList books=root.getChildNodes();
for(int i=0;i<books.getLength();i++){
Node book=books.item(i);
}
這是用一個org.w3c.dom.NodeList接口來存放它所有子節(jié)點(diǎn)的,還有一種輪循子節(jié)點(diǎn)的方法,后面有介紹
(7)取得節(jié)點(diǎn)的屬性值
String email=book.getAttributes().getNamedItem("email").getNodeValue();
System.out.println(email);
注意,節(jié)點(diǎn)的屬性也是它的子節(jié)點(diǎn)。它的節(jié)點(diǎn)類型也是Node.ELEMENT_NODE
(8)輪循子節(jié)點(diǎn)
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:其它關(guān)于解析問題
何時使用 SAX?何時使用 DOM?
文本大用SAX 消耗內(nèi)存大 ; 如果要來回讀 要用DOM
JAXP-------javax.xml.parser(sun公司的API 包含了上面兩種API 是類不是接口 只是一個入口 )-----統(tǒng)一接口,默認(rèn)解析器
其他公司的工具包
JDOM(基于DOM)
Dom4j(基于DOM)最流行
Apache Xerces(基于SAX)