package com.itheima.sax; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; public class SaxDemo1 { public static void main(String[] args) throws Exception { //1.獲取解析器工廠 SAXParserFactory factory = SAXParserFactory.newInstance(); //2.通過工廠獲取sax解析器 SAXParser parser = factory.newSAXParser(); //3.獲取讀取器 XMLReader reader = parser.getXMLReader(); //4.註冊事件處理器 reader.setContentHandler(new MyContentHandler2() ); //5.解析xml reader.parse("book.xml"); } } //介面卡設計模式 class MyContentHandler2 extends DefaultHandler{ private String eleName = null; private int count = 0; @Override public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { this.eleName = name; } @Override public void characters(char[] ch, int start, int length) throws SAXException { if("書名".equals(eleName) && ++count==2){ System.out.println(new String(ch,start,length)); } } @Override public void endElement(String uri, String localName, String name) throws SAXException { eleName = null; } } class MyContentHandler implements ContentHandler{ public void startDocument() throws SAXException { System.out.println("文件解析開始了......."); } public void startElement(String uri, String localName, String name, Attributes atts) throws SAXException { System.out.println("發現了開始標籤,"+name); } public void characters(char[] ch, int start, int length) throws SAXException { System.out.println(new String(ch,start,length)); } public void endElement(String uri, String localName, String name) throws SAXException { System.out.println("發現結束標籤,"+name); } public void endDocument() throws SAXException { System.out.println("文件解析結束了......."); } public void endPrefixMapping(String prefix) throws SAXException { // TODO Auto-generated method stub } public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub } public void processingInstruction(String target, String data) throws SAXException { // TODO Auto-generated method stub } public void setDocumentLocator(Locator locator) { // TODO Auto-generated method stub } public void skippedEntity(String name) throws SAXException { // TODO Auto-generated method stub } public void startPrefixMapping(String prefix, String uri) throws SAXException { // TODO Auto-generated method stub } }
Document document = reader.read(new File("input.xml"));
ele.addElement("age");
Attribute attr= ele.attribute("aaa");
ele.remove(attribute);
Document document = DocumentHelper.parseText(text);
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"));
writer.write(node);
writer.close();
XMLWriter writer =
你所應該知道的Dom4J
建立解析器:
SAXReader reader = new SAXReader();
利用解析器讀入xml文件:
Document document = reader.read(new File("input.xml"));
獲取文件的根節點:
Element root = document.getRootElement();
介面繼承結構:
Node ---
Branch
--Document
--Element
----
Attribute
Node介面
asXML() 將一個節點轉換為字串 |
|
getName() 獲取節點的名稱,如果是元素則獲取到元素名,如果是屬性獲取到屬性名 |
|
short |
getNodeType() 獲取節點型別,在Node介面上定義了一些靜態short型別的常量用來表示各種型別 |
getParent() 獲取父節點,如果是根元素呼叫則返回null,如果是其他元素呼叫則返回父元素,如果是屬性呼叫則返回屬性所依附的元素。 |
|
getText() 返回節點文字,如果是元素則返回標籤體,如果是屬性則返回屬性值 |
|
selectNodes(String xpathExpression) 利用xpath表示式,選擇節點 |
|
void |
setName(String name) 設定節點的名稱,元素可以更改名稱,屬性則不可以,會丟擲UnsupportedOperationException 異常 |
void |
setText(String text) 設定節點內容,如果是元素則設定標籤體,如果是屬性則設定屬性的值 |
void |
write(Writer writer) 將節點寫出到一個輸出流中,元素、屬性均支援 |
Branch介面(實現了Node介面)
void |
add(Element element) 增加一個子節點 |
addElement(QName qname) 增加一個給定名字的子節點,並且返回這個新建立的節點的引用 |
|
int |
indexOf(Node node) 獲取給定節點在所有直接點中的位置號,如果該節點不是此分支的子節點,則返回-1 |
boolean |
remove(Element element) 刪除給定子元素,返回布林值表明是否刪除成功。 |
void |
add(Attribute attribute) 增加一個屬性 |
addAttribute(QName qName, String value) 為元素增加屬性,用給定的屬性名和屬性值,並返回該元素 |
|
addAttribute(String name, String value) 為元素增加屬性 |
|
attribute(int index) 獲取指定位置的屬性 |
|
attribute(QName qName) 獲取指定名稱的屬性 |
|
attributeIterator() 獲取屬性迭代器 |
|
attributes() 獲取該元素的所有屬性,以一個list返回 |
|
attributeValue(QName qName) 獲取指定名稱屬性的值,如果不存在該屬性返回null,如果存在該屬性但是屬性值為空,則返回空字串 |
|
element(QName qName) 獲取指定名稱的子元素,如果有多個該名稱的子元素,則返回第一個 |
|
element(String name) 獲取指定名稱的子元素,如果有多個該名稱的子元素,則返回第一個 |
|
elementIterator() 獲取子元素迭代器 |
|
elementIterator(QName qName) 獲取指定名稱的子元素的迭代器 |
|
elements() 獲取所有子元素,並用一個list返回 |
|
elements(QName qName) 獲取所有指定名稱的子元素,並用一個list返回 |
|
getText() 獲取元素標籤體 |
|
boolean |
remove(Attribute attribute) 移除元素上的屬性 |
void |
setAttributes(List attributes) 將list中的所有屬性設定到該元素上 |
Attribute介面(實現了Node介面)
getQName() 獲取屬性名稱 |
|
getValue() 獲取屬性的值 |
|
void |
setValue(String value) 設定屬性的值 |
DocumentHelper 類
static Attribute |
createAttribute(Element owner, QName qname, String value) 建立一個Attribute |
|
static Document |
建立一個Document |
|
static Document |
createDocument(Element rootElement) 以給定元素作為根元素建立Document |
|
|
static Element |
createElement(QName qname) 以給定名稱建立一個Element |
static Document |
parseText(String text) 將一段字串轉化為Document |
將節點寫出到XML檔案中去
方法1:
呼叫Node提供的write(Writer writer) 方法,使用預設方式將節點輸出到流中:
node.write(new FileWriter("book.xml"));
亂碼問題:
Dom4j在將文件載入記憶體時使用的是文件宣告中encoding屬性宣告的編碼集進行編碼, 如果在此時使用writer輸出時writer使用的內部編碼集與encoding不同則會有亂碼問題。
FileWriter預設使用作業系統本地碼錶即gb2312編碼,並且無法更改。
此時可以使用OutputStreamWriter(FileOutputStream("filePath"),"utf-8");的方式自己封裝 一個指定碼錶的Writer使用,從而解決亂碼問題。
方式2:
利用XMLWriter寫出Node:
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"));
writer.write(node);
writer.close();
亂碼問題:
(1)使用這種方式輸出時,XMLWriter首先會將記憶體中的docuemnt翻譯成UTF-8 格式的document,在進行輸出,這時有可能出現亂碼問題。
可以使用OutputFormat 指定XMLWriter轉換的編碼為其他編碼。
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("GBK");
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"),format);
(2)Writer使用的編碼集與文件載入記憶體時使用的編碼集不同導致亂碼,使用位元組流 或自己封裝指定編碼的字元流即可(參照方法1)。
package com.itheima.dom4j; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class Dom4jDemo1 { public static void main(String[] args) throws Exception { //1.獲取解析器 SAXReader reader = new SAXReader(); //2.解析xml獲取代表整個文件的dom物件 Document dom = reader.read("book.xml"); //3.獲取根節點 Element root = dom.getRootElement(); //4.獲取書名進行列印 String bookName = root.element("書").element("書名").getText(); System.out.println(bookName); } }
package com.itheima.dom4j; import java.io.FileOutputStream; import java.util.List; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import org.junit.Test; public class Demo4jDemo2 { @Test public void attr() throws Exception{ SAXReader reader = new SAXReader(); Document dom = reader.read("book.xml"); Element root = dom.getRootElement(); Element bookEle = root.element("書"); //bookEle.addAttribute("出版社", "傳智出版社"); // String str = bookEle.attributeValue("出版社"); // System.out.println(str); Attribute attr = bookEle.attribute("出版社"); attr.getParent().remove(attr); XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint()); writer.write(dom); writer.close(); } @Test public void del() throws Exception{ SAXReader reader = new SAXReader(); Document dom = reader.read("book.xml"); Element root = dom.getRootElement(); Element price2Ele = root.element("書").element("特價"); price2Ele.getParent().remove(price2Ele); XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint()); writer.write(dom); writer.close(); } @Test public void update()throws Exception{ SAXReader reader = new SAXReader(); Document dom = reader.read("book.xml"); Element root = dom.getRootElement(); root.element("書").element("特價").setText("4.0元"); XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint()); writer.write(dom); writer.close(); } @Test public void add()throws Exception{ SAXReader reader = new SAXReader(); Document dom = reader.read("book.xml"); Element root = dom.getRootElement(); //憑空建立<特價>節點,設定標籤體 Element price2Ele = DocumentHelper.createElement("特價"); price2Ele.setText("40.0元"); //獲取父標籤<書>將特價節點掛載上去 Element bookEle = root.element("書"); bookEle.add(price2Ele); //將記憶體中的dom樹會寫到xml檔案中,從而使xml中的資料進行更新 // FileWriter writer = new FileWriter("book.xml"); // dom.write(writer); // writer.flush(); // writer.close(); XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint()); writer.write(dom); writer.close(); } @Test public void find() throws Exception{ SAXReader reader = new SAXReader(); Document dom = reader.read("book.xml"); Element root = dom.getRootElement(); List<Element> list = root.elements(); Element book2Ele = list.get(1); System.out.println(book2Ele.element("書名").getText()); } }