SAX解析和xml約束
一、SAX解析
1.特點
SAX解析:讀一點,取一點,節省內存空間。一旦遇到開始標簽觸發之后,及時從內存中將開始節點從內存中釋放點。
2.三要素
/**
* SAX解析:針對事件編程
* 三要素:
* 1)事件源
* 2)事件監聽器
* 遇到文檔開始 startDocument(......)
* 遇到開始標簽 startElement(......)
* 遇到文本內容 characters(......)
* 遇到結束標簽 endElement(......)
* 遇到文檔結束 endDocument(......)
* 3)注冊事件監聽器:基于事件處理程序
* DefaultHandler
* 開發步驟:
* 1)創建SAX解析器對象
* 2)解析當前xml文件
* 3)基于事件處理進行判斷(開始標簽/結束標簽/文本內容)
*/
3.DOM解析和SAX解析的區別
原理:前者,讀一點,取一點,節省內存空間。一旦遇到開始標簽觸發之后,及時從內存中將開始節點從內存中釋放點。
后者,一次性加載整個xml文件,如果xml文件結構層次深,可能會導致OOM異常,浪費空間。
使用過程區別:前者,只能去讀(需求:使用SAX解析,將xx.xml文件原封不動打印)
后者:不僅能讀,還能寫,并且能往返讀。
編程思想:前者,面向事件編程方式---->Java開發者難理解。
后者,面向對象編程思想,編程方式--->Java開發者好理解。
二、SAX解析的使用
1.使用SAX解析xml文件
xml文件為:
<?xml version="1.0" encoding="utf-8" ?>
<!--使用xml文件來標簽聯系人,姓名 性別 電話-->
<contact id="001">
<name>張三</name>
<phone>18292886805</phone>
<gender>男</gender>
</contact>
package com.xunpu.sax;
/**
* SAX解析:
* 讀一點,取一點。節省空間,一旦遇到開始標簽觸發之后,及時從內存中將開始節點內存中釋放。
*/
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* 編寫監聽器:自定義類 繼續自基類(DefaultHandler)
*/
public class MyDefault1 extends DefaultHandler {
/**
*
* @param uri
* @param localName
* @param qName 開始標簽名稱<contact id="" name="">
* @param attributes 屬性列表
* @throws SAXException
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.println("MyDefaultHandler1.startDociment:"+qName);
}
/**遇到文本內容
* @param ch
* @param start
* @param length
* @throws SAXException
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
//遇到文本:每次讀取到的是當前文本的實際內容
String content=new String(ch,start,length);
System.out.println("文檔內容:"+content);
}
/**
* @param uri
* @param localName
* @param qName 結束標簽名稱
* @throws SAXException
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println("MyDefaultHandler1.endElement:"+qName);
}
/**
*
* @throws SAXException
*/
@Override
public void endDocument() throws SAXException {
System.out.println("MyDefault endDocument:森當解析結束了");
}
}
package com.xunpu.sax;
import org.dom4j.Document;
import org.dom4j.io.SAXReader;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
public class SAXDemo {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//1)創建一個SAX解析器對象 SAXParse--抽象類 使用它的工廠類創建對象。
SAXParser parser=SAXParserFactory.newInstance().newSAXParser();
//2)讀取xml文件
//事件源:解析contact.xml
parser.parse(SAXDemo.class.getClassLoader().getResourceAsStream("contact.xml"),
new MyDefault1());
}
}
注意:xml文件首行的拼寫一定不能出現錯誤,否則就會出現"Exception in thread "main" org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 21; 應該有偽屬性名。"類錯誤。
結果:
解析過程:
<contact id="001"> ------>startElement(qname,Attribute) 開始元素的觸發事件
<name>張三------->張三:characters(ch,start,length) 文本觸發事件
</name></contact>--------->endElement(qname,....) 結束標簽觸發的事件
2.使用SAX解析將xml文件原封不動輸出
步驟:
1)創建解析器
2)讀取xml文件
3)定義一個基于事件的處理程序(一個類 extends DefaultHandler)
使用字符串緩沖區對象StringBuffer
定義一個方法-->可以將字符緩沖區的內容-->String類型。
package com.xunpu.sax;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
//基于事件的處理程序
public class MyDefault2 extends DefaultHandler {
private StringBuffer sb=new StringBuffer();
//定義一個成員方法
public String getContent(){
return sb.toString();
}
//遇到開始標簽 qName:標簽名稱
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
sb.append("<"+qName);
//遍歷屬性列表 getLength():返回屬性列表的長度
for(int i=0;i<attributes.getLength();i++){
//獲取到每一個屬性對象
String attributesName=attributes.getQName(i);
String attrValue=attributes.getValue(i);
//雙引號需要轉義
sb.append(" "+attributesName+"=\""+attrValue);
}
sb.append(">");
}
//遇到文本內容
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String content=new String(ch,start,length);
sb.append(content);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
sb.append("</"+qName+">");
}
}
package com.xunpu.sax;
import org.dom4j.io.SAXReader;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
public class SAXDemo2 {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
SAXParser parser=SAXParserFactory.newInstance().newSAXParser();
MyDefault2 handler2=new MyDefault2();
parser.parse(SAXDemo2.class.getClassLoader().getResourceAsStream("contact.xml"),handler2);
String content=handler2.getContent();
System.out.println(content);
}
}
結果:
三、xml文件的約束(簡介)
1.dtd約束
<!--內部方式-->
<!DOCTYPE note[
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
note.xml文件
<!--外部方式 note是根節點 約束為note.dtd文件-->
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
note.dtd文件:
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
外部文件一些約束的聲明:
<!--聲明屬性:
<!ATTLIST 元素名稱 屬性名稱 屬性類型 默認值>
CDATA:普通字符串
<!ATTLIST body id CDATA #REQUIRED> :約束body的內容是普通字符串而且必須指定id屬性。
<!ATTLIST body id CDATA #FIXED "002"> :約束body的內容是普通字符串而且必須id屬性值必須是"002",否則值無效。
-->
2.schema約束
名稱空間的定義格式: xmlns:名稱空間="別名"(URL)
如:
<bite:書架 xmlns:bite="http://www.bite.cn"
xmlns:xsi="htttp://wwwww.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.bite.cn book.xsd">
在第一行中,bite是名稱空間,"http://www.bite.cn"是別名。
schemaLocation中指代的文件是用來約束書架的!!
使用名稱空間:1)使用名稱空間在xml中定義標簽,必須指定別名。如:“http://www.bite.cn”
2)關聯當前別名地址:schemaLocation="別名1 地址1 別名2 地址2....."。
定義后的名稱空間,指定標簽名稱格式:名稱空間:標簽名稱(如bite:書架)----->書架標簽被book.xsd文件所約束。
xxx.xsd:schema約束文件
w3c組織定義的格式:xs:約束xml文件定義的標簽。
Schema約束(類型豐富) 是基于 XML 的 DTD 替代者。
智能推薦
XML:SAX解析
SAX解析 SAX采用事件處理的方式解析XML文件,利用 SAX 解析 XML 文檔,涉及兩個部分:解析器和事件處理器。 解析器可以使用JAXP的API創建,創建出SAX解析器后,就可以指定解析器去解析某個XML文檔。 解析器采用SAX方式在解析某個XML文檔時,它只要解析到XML文檔的一個組成部分,都會去調用事件處理器的一個方法,解析器在調用事件處理器的方法時,會把當前解析到的xml文件內容作為...
SAX解析XML文件
SAX解析XML文件 使用SAX解析時,首先要定義一個專屬的解析器,這個解析器必須繼承一個父類org.xml.sax.helpers.DefaultHandler,在這個類中有如下方法: No 返回值 方法名 描述 1 void startDocument() 文檔開始讀取時觸發 2 void endDocument() 文檔讀取完畢后出發 3 void startElement(String u...
sax 解析xml
本文是參考別人的寫的, 地址忘了,拿人手短,提前聲明一下。 解析步驟: 1.創建一個SAXParserFactory對象 SAXParserFactory factory=SAXParserFactory.newInstance(); 2.獲得解析器 SAXParser parser=factory.newSAXParser(); 3.調用解析方法解析xml,這里的第一個參數可以傳遞文件、流、字符...
SAX解析XML
什么是XML? XML 指可擴展標記語言(eXtensible Markup Language)。 你可以通過本站學習XML教程 XML 被設計用來傳輸和存儲數據。 XML是一套定義語義標記的規則,這些標記將文檔分成許多部件并對這些部件加以標識。 它也是元標記語言,即定義了用于定義其他與特定領域有關的、語義的、結構化的標記語言的句法語言。 python對XML的解析 常見的XML編程接口有DOM和...
猜你喜歡
XML(三):xml的解析技術:dom和sax
1. 解析過程圖及優缺點 2.針對dom和sax的解析器 3.JAXP 使用 1)javax.xml.parsers包下有四個類: DocumentBuilder和DocumentBuilderFactory、 SaxParser和SaxParserFactory 2)步驟:...
XML的SAX解析以及DOM解析和SAX解析區別
前言: XML解析工具 老樣子,三個問題: SAX是什么? 也是用來解析XML的 SAX解析工具- 內置在jdk中。org.xml.sax.* SAX運用場景? SAX解析原理: 加載一點,讀取一點,處理一點。對內存要求比較低。 SAX解析工具核心: 核心的API: 參數一: File:表示 讀取的xml文件。 參數二: DefaultHandler: SAX事件處理程序。使用DefaultHan...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...