在JAVA中,解析有三種方式: Dom解析(支持改刪,耗記憶體)、 Sax解析(不支持改刪,不耗記憶體)、 Pull解析(在Android中推薦使用的一種解析XML的方式,在下章學習)、 1.支持Dom與Sax解析的開發包 分為兩種. JAXP: 由sun公司推出的解析標準實現(本章只學習該包的解析方法 ...
在JAVA中,解析有三種方式:
- Dom解析(支持改刪,耗記憶體)、
- Sax解析(不支持改刪,不耗記憶體)、
- Pull解析(在Android中推薦使用的一種解析XML的方式,在下章學習)、
1.支持Dom與Sax解析的開發包
分為兩種.
- JAXP: 由sun公司推出的解析標準實現(本章只學習該包的解析方法)
- Dom4j: 一種開源的解析開發包.
jaxp是java api中自帶的一個包,而dom4j需要我們加入jar文件才能使用
2.JAXP使用
JAXP(Java API for XMLProcessing)主要由下麵幾個包組成:
- org.w3c.dom: 定義DOM解析器的標準介面
- org.w3c.sax: 定義SAX解析器的標準介面
- javax.xml:提供解析xml文檔的類
- javax.xml.parsers:提供了用來獲取DOM和SAX解析器對象的工廠類,比如:DocumentBuilderFactory(創建DOM解析器對象)、SAXParserFactory,如下圖所示:
3.使用JAXP進行DOM解析
會將XML文檔全部內容都讀入記憶體中,並且將文檔里的每個數據都創建為一個個對象,所以方便增刪改.並且遍歷簡單。
DOM的缺點主要表現在:效率低,解析速度慢,記憶體占用量過高,對於大文件來說幾乎不可能使用。
3.1 persons.xml示例如下:
<?xml version="1.0" encoding="UTF-8"?> <persons> <person> <姓名>張三</姓名> <性別>男</性別> <年齡>22</年齡> </person> <person> <姓名>李四</姓名> <性別>男</性別> <年齡>17</年齡> </person> </persons>
3.2 DOM讀取xml步驟
1.通過DocumentBuilderFactory.newInstance()靜態方法得到創建 DOM 解析器的工廠對象(DocumentBuilderFactory)
2.通過工廠對象的newDocumentBuilder()方法得到 DocumentBuilder解析器對象
3.然後通過DocumentBuilder解析器對象的parse(filename)方法來得到解析xml文檔的Document對象
4.通過Document對象的成員方法來獲取XML文檔的元素信息,比如getElementsByTagName("person")方法來獲取xml文件中的person元素(返回的類為NodeList,保存person所有的集合,比如list.item(0). getTextContent()列印第一個元素的內容)
具體實現方法如下:
@Test public void DomReadXml() throws Exception{ //獲取工廠實例 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); //創建builder DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); //解析xml Document document = documentBuilder.parse("src//persons.xml"); //讀出元素內容 System.out.println("第一個姓名:"+document.getElementsByTagName("姓名").item(0).getTextContent()); //讀出元素內容 System.out.println("第二個姓名:"+document.getElementsByTagName("姓名").item(1).getTextContent()); }
列印:
3.3 DOM修改xml步驟
1.先將xml信息讀取到Document對象中
2.然後通過getElementsByTagName("person")方法來獲取xml文件中的person元素(返回的類為NodeList),然後通過NodeList.item(i).setTextContent("text")來修改節點內容
3.修改完成後通過Transformer類的transform(Source , Result )方法來將改過的Document對象寫入XML文件
具體實現方法如下:
@Test public void DomWriteXml() throws Exception{ DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); //1.先將xml信息讀取到Document對象中 Document document = documentBuilder.parse("src//persons.xml"); //2.修改第一個節點內容為99 document.getElementsByTagName("年齡").item(0).setTextContent("99"); //3.通過transform(Source , Result )方法來將改過的Document對象寫入XML文件 Transformer transformer = TransformerFactory.newInstance().newTransformer(); Source xmlSource = new DOMSource(document); Result outputTarget = new StreamResult("src//persons.xml"); transformer.transform(xmlSource, outputTarget); }
4.使用JAXP進行SAX解析
sax解析的優點是邊讀邊解析,占用記憶體少,解析速度快,缺點是不能對XML文件改刪,並且不支持向後遍歷,只能從頭到尾讀取.
4.1 SAX讀取XML步驟
1.獲取SAXParser對象,該對象通過SAXParserFactory構造
2.通過SAXParser.getXMLReader()獲取XMLReder對象
3.實現一個ContentHandler的子類(PersonHandler),其實就是構造一個DefaultHandler的子類(因為contentHandler介面太多方法沒實現),如下圖所示:
然後重寫startElement()等方法(用來實現具體的XML讀取)
4.再調用XMLReder對象的setContentHandler(new PersonHandler())來設置我們要解析的具體handler
5.最後調用XMLReder對象的parse(file),開始進行解析
4.2 Myhandler需要重寫的方法有以下幾個
startDocument(); //當文檔開始解析時,觸發該方法 endDocument(); //當文檔解析完成時,觸發該方法 startElement(String uri, String localName, String qName, Attributes attributes) //解析到開始元素時,觸發該方法 endElement(String uri, String localName, String qName) //解析到結束元素時,觸發該方法 //uri:名稱空間URI,如果元素沒有名稱空間,沒有則為空字元串。 //localName:本地名稱(不帶首碼),沒有則為空字元串。 //qName:元素名(帶有首碼),如果元素名不可用則為空字元串。 //attributes:該元素的所有屬性。如果沒有屬性,則為空對象. characters(char[] ch, int start, int length) //接收字元內容時,觸發該方法,比如"<姓名>李四</姓名>",當解析到"李四"時,會調用到該方法,並將"李四"作為參數傳遞進來.
4.3 persons.xml示例如下:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <persons> <person> <姓名>張三</姓名> <性別>男</性別> <年齡>99</年齡> </person> <person> <姓名>李四</姓名> <性別>男</性別> <年齡>17</年齡> </person> </persons>
4.4 Person類如下所示:
public class Person { private String name; private String sex; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]"; } }
4.5 SaxParseTest類如下所示:
package com.my.xmlparser; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.junit.Test; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; import com.my.bean.Person; class PersonHandler extends DefaultHandler{ private String status=null; private ArrayList<Person> persons=null; private Person person=null; @Override public void startDocument() throws SAXException { persons = new ArrayList<Person>(); person = new Person(); } @Override public void endDocument() throws SAXException { for(Person person1:persons){ //列印所有信息 System.out.println(person1); } } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { status = qName; } @Override public void endElement(String uri, String localName, String qName) throws SAXException { status =null; if("person".equals(qName)) //添加一個person { persons.add(person); person = new Person(); } } @Override public void characters(char[] ch, int start, int length) throws SAXException { String text = new String(ch,start,length); if(status == null) return; else if("姓名".equals(status)) { person.setName(text); } else if("性別".equals(status)) { person.setSex(text); } else if("年齡".equals(status)) { person.setAge(text); } } } public class SaxParseTest { @Test public void SaxParse() throws Exception{ //1.獲取SAXParser對象,該對象通過SAXParserFactory構造 SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); SAXParser saxParser = saxParserFactory.newSAXParser(); //2.通過SAXParser.getXMLReader()獲取XMLReder對象 XMLReader reader = saxParser.getXMLReader(); //3~4:實現一個ContentHandler的子類(Myhandler),然後來設置我們要解析的具體handler reader.setContentHandler(new PersonHandler()); //5.最後調用XMLReder對象的parse(file),開始進行解析 reader.parse("src//persons.xml"); } }
測試運行:
未完待續,下章學習pull解析