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)