package a01JavaWebXML;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
/*
* iso8859-1(latin1)-1字節1字符
* GBK-GBK2312------ 2字節1字符包含中文
* unicode-----------3字節1字符
* UTF-8 UTF-16 ----3字節一箇中文 生僻字4字節
*/
/*
*
* SAX解析
* Java官方提供的解析
* pull解析
*
*
* SAX解析流程
* <root> ->startDocument
* <first> ->startElement qName=first
* 1 ->characters 1
* <first> ->endElement qName=first
*</root> ->endDocument
*
*
*/
public class JavaWebXMLSax {
public static void main(String[] args) throws Exception{
//1.使用SAXParserFactory創建SAX解析工廠
SAXParserFactory factory=SAXParserFactory.newInstance();
//2.通過SAX解析工廠得到解析器對象
SAXParser paser=factory.newSAXParser();
//3.通過解析器對象得到一個XML的讀取器
XMLReader reader=paser.getXMLReader();
//4.設置讀取器的事件處理器
reader.setContentHandler(new MyHandler2());
//5.解析xml文件
reader.parse("E:\\ChenXunCode\\TarenaBigData\\JavaWeb\\book.xml");
}
}
//獲取第二本書的書名的名字
//自己定義的事件處理器
class MyHandler2 extends DefaultHandler{
private String eleName = null;
private int count = 0;
//開始解析節點 startElement() 開始標籤qName
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
eleName = qName; //節點剛開始,eleName記錄開始節點,且count++
if("書名".equals(eleName)){
count++;
}
}
//保存節點內容 characters() 標籤體new String(ch,start,length)
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if("書名".equals(eleName) && count == 2){ //如果是第二個書籤,且書籤名爲書名,就打印第二本書的書名的名字
String str = new String(ch,start,length);
System.out.println(str);
}
}
//結束解析節點 endElement() 結束標籤qName
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if("書名".equals(qName)){ //節點結束,eleName爲空
//-------------------注意聽一下--------------------------------------------
eleName = null;
}
}
}
class MyHandle1 extends DefaultHandler{
// 開始解析文檔 startDocument()
@Override
public void startDocument() throws SAXException {
System.out.println("文檔解析開始了。。。");
}
//開始解析節點 startElement() 開始標籤qName
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.println("發現了元素的開始標籤"+qName);
}
//保存節點內容 characters() 標籤體new String(ch,start,length)
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
System.out.println("發現了標籤體"+new String(ch,start,length));
}
//結束解析節點 endElement() 結束標籤qName
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println("發現了元素的結束標籤"+qName);
}
//文檔解析結束 endDocument()
@Override
public void endDocument() throws SAXException {
System.out.println("文檔解析結束了。。");
}
}
package a01JavaWebXML;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/*
*
* Dom解析
* Java官方提供的解析
* Dom4j解析
* 還有一種
*
*/
//思想:1.先獲取根節點root getRootElement()
// 2.根節點下的所有"書"節點的第二個boo2file root.elements("書").get(1)
// 3.這個第二個"書"節點下的"書名"子節點bookNameFile book2file.element("書名")
// 4.獲取"書名"子節點裏面的內容bookName bookNameFile.getText()
//獲取第二本書的書名的名字
public class JavaWebXMLDom {
public static void main(String[] args) throws Exception {
//1.創建解析器 SAXReader
SAXReader reader = new SAXReader();
//2.利用解析器讀取xml文件 SAXReader.read(文件)
Document dom = reader.read("book.xml");
//3.獲取根節點 Document.getRootElement()
Element root = dom.getRootElement();
//4.獲取<書架>下的第二個節點
Element book2file=(Element) root.elements("書").get(1);
//上面這一步等價於下面兩步
//獲取root下所有節點集合 List<Element> list = root.elements("書");
//獲取第二個元素 Element bookEle2 = list.get(1);
Element bookNameFile=book2file.element("書名");
String bookName=bookNameFile.getText();
System.out.println(bookName);
}
}
package a01JavaWebXML;
import java.io.FileOutputStream;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
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;
/*
* Dom解析
* <?xml version="1.0" encoding="utf-8" ?>
* <root>
* <head>
* <title>example<title>
* </head>
* <body>
* <p>cont1</p>
* <p>cont2</p>
* </body>
* <foot>
* <author name="wuyun"/>
* </foot>
*
* </root>
*
*
*
*
* 基於DOM的XML解析器將一個XML文檔轉換成一個對象模型的集合(通常稱DOM樹),
* 應用程序通過對這個對象模型的操作,來實現對XML文檔數據的操作。
* Document:dom
*
* Element:root
*
* Element:head Element:body Element:foot
* | | | |
* Element:title Element:p Element:p Element:author
* | | |
* Character:example Character:cont1 Character:cont2 Attr:name
*
*
*
*
* dom
* 書架
* 書 書
* 書名 作者 售價 書名 作者 售價
*/
public class JavaWebXMLDom02Operator {
//1.獲取某個節點的值
//輸出55.00元
@Test
public void getEle() throws Exception{
//1.獲取解析器 解析xml獲取dom 通過dom獲取根節點
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement(); //獲取根節點
//2.通過根節點獲取需要的元素
Element bookEle = (Element) root.elements("書").get(1);//獲取<書架>下的第二個節點<書>
//上面這一步等價於下面兩步
//獲取root下所有節點集合 List<Element> list = root.elements("書");
//獲取第二個元素 Element bookEle2 = list.get(1);
Element priceEle = bookEle.element("售價"); //獲取<書>節點下的<售價>節點
String str = priceEle.getText();
System.out.println(str);
}
//2.增加一個子節點 createElement()
// DocumentHelper.createElement(節點名) Elements.setText() Elements.add(Elements)
@Test
public void addEle() throws Exception{
//1.獲取解析器 解析xml獲取dom 通過dom獲取根節點
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
//--------------------start增加一個子節點--------------------
//2.憑空創建<特價>節點並且設置標籤體爲 0.5元
Element price2Ele = DocumentHelper.createElement("特價"); //創建Document對象 DocumentHelper.createElement()
price2Ele.setText("0.5元");
//3.獲取第二個<書>節點
Element book2Ele = (Element) root.elements("書").get(1);
//4.將<特價>掛載到<書>節點上
book2Ele.add(price2Ele);
//---------------------end增加一個子節點--------------------
//注意:以上修改只是在內存中修改dom信息,不寫回文件的,文件中的信息不會修改
//5.第一種方式:將內存中的dom信息寫回文件
//OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("book.xml"), "utf-8");
//dom.write(writer);
//writer.flush();
//writer.close();
//5.第二種方式:將內存中的dom信息寫回文件
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),format);
writer.write(dom);
writer.flush();
writer.close();
}
//3.刪除一個子節點
@Test
public void removeEle() throws Exception{
//1.獲取解析器 解析xml獲取dom 通過dom獲取根節點
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
//--------------------start刪除一個子節點--------------------
// Element.getParent().remove(Element)
//2.獲取第二個<作者>節點
Element authorEle= ((Element) root.elements("書").get(1)).element("作者");
//3.從<作者>節點的父節點中移除<作者>節點
authorEle.getParent().remove(authorEle);
//--------------------end刪除一個子節點--------------------
//注意:以上修改只是在內存中修改dom信息,不寫回文件的,文件中的信息不會修改
//4.將內存中的dom輸出到文件中
XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint());
writer.write(dom);
writer.flush();
writer.close();
}
//4.增加一個屬性 createAttribute()
// DocumentHelper.createAttribute(節點, 屬性, 屬性值); Elements.add(attr)
@Test
public void addAttr() throws Exception{
//1.獲取解析器 解析xml獲取dom 通過dom獲取根節點
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
//-------------------start增加一個屬性----------------------
//2.獲取第二個<書>節點
Element book2Ele = (Element) root.elements("書").get(1);
//3.憑空創建屬性 出版社="達內出版社"
Attribute attr = DocumentHelper.createAttribute(book2Ele, "出版社", "達內出版社");
//4.將屬性掛載到節點上
book2Ele.add(attr);
//-------------------end增加一個屬性----------------------
//5.寫出dom到文件
XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint());
writer.write(dom);
writer.flush();
writer.close();
}
//5.獲取一個屬性
// Elements.attribute(屬性名) Attribute.getName() Attribute.getValue()
@Test
public void getAttr() throws Exception{
//1.獲取解析器 解析xml獲取dom 通過dom獲取根節點
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
//2.獲取第二個<書>節點
Element book2Ele = (Element) root.elements("書").get(1);
//-------------------start獲取一個屬性-----------------
//3.獲取<書>上的屬性
Attribute attr = book2Ele.attribute("出版社");
String name = attr.getName();
String value = attr.getValue();
System.out.println(name+"~"+value);
//------------------end獲取一個屬性-----------------------------------
}
//6.刪除一個屬性
//Element.attribute(屬性名) Element.remove(attr)
@Test
public void removeAttr() throws Exception{
//1.獲取解析器 解析xml獲取dom 通過dom獲取根節點
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
//2.獲取第二個<書>節點
Element book2Ele = (Element) root.elements("書").get(1);
//----------start刪除一個屬性--------------------------------
//3.獲取<書>上的屬性
Attribute attr = book2Ele.attribute("出版社");
//4.從<書>節點上移除指定屬性
book2Ele.remove(attr);
//----------end刪除一個屬性---------------------------------
//5.將內存中的dom寫出到文件中
//注意:如果不寫這步,僅在內存中操作整個xml文件,實際xml未變
XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint());
writer.write(dom);
writer.flush();
writer.close();
}
//----------------創建xml文件createDocument()-------------------------------------
@Test
public void createDom() throws Exception{
//1.直接內存中構建一個Dom DocumentHelper.createDocument()
Document dom = DocumentHelper.createDocument();
//2.創建各個節點元素 DocumentHelper.createElement(節點名)
Element ChinaEle = DocumentHelper.createElement("中國");
Element bjEle = DocumentHelper.createElement("北京");
Element shEle = DocumentHelper.createElement("上海");
Element gzEle = DocumentHelper.createElement("廣州");
Element hdEle = DocumentHelper.createElement("海淀");
hdEle.setText("配電腦");
Element pgEle = DocumentHelper.createElement("平谷");
pgEle.setText("桃");
//3.掛在節點上
dom.add(ChinaEle); //Document.add() 根節點<中國>
ChinaEle.add(bjEle); //<中國>節點下有<北京><上海><廣州>
ChinaEle.add(shEle);
ChinaEle.add(gzEle);
bjEle.add(hdEle); //<北京>節點下有<海淀><平谷>
bjEle.add(pgEle);
//4.輸出到文件
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(new FileOutputStream("country.xml"),format);
writer.write(dom);
writer.flush();
writer.close();
}
/*
*
上面輸出counrty.xml文件,裏面內容爲
<?xml version="1.0" encoding="UTF-8"?>
<中國>
<北京>
<海淀>配電腦</海淀>
<平谷>桃</平谷>
</北京>
<上海/>
<廣州/>
</中國>
*/
}
package a01JavaWebXML;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/*
* dom4j -XPath
*
*1.從根路徑開始的絕對路徑方式獲取/AAA
例子:獲取所有AAA下的BBB下的所有CCC:/AAA/BBB/CCC
2.所有指定名稱的元素//AAA
例子:獲取所有名稱爲AAA的元素
3.使用*號匹配符獲得所有滿足條件的元素
例子:獲取AAA下BBB下所有的元素:/AAA/BBB/*
4.使用中括號,獲取多個匹配元素中的某一個,可以使用last()函數獲取最後一個
例子:獲取AAA下所有BBB的第二個:/AAA/BBB[2]
例子:獲取AAA下所有BBB的最後一個:/AAA/BBB[last()]
5.指定某一屬性:@AttName,可以配合中括號使用
例子:獲取所有id屬性://@id
例子:獲取所有具有id屬性的BBB元素://BBB[@id]
例子:獲取所有不具有屬性的BBB元素://BBB[not(@*)]
例子:獲取屬性的值爲某一個固定值的BBB元素://BBB[@id='b1']
*
*
*/
public class JavaWebXMLDom03XPath {
public static void main(String[] args) throws Exception {
//1.創建解析器 解析xml獲取dom 獲取根節點
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
//2.通過xpath獲取需要的元素
//注意:Element.selectSingleNode(xpathQuery) 選擇匹配 XPath 表達式的第一個
//xpath下的[num] 例如書[2]就是第二個書節點,不是第三個書節點
Element book2Ele = (Element) root.selectSingleNode("//書[2]/書名"); //獲取第一個滿足 第二個"書"節點下的"書名"節點
System.out.println(book2Ele.getText());
//3.通過xpath獲取屬性
//注意:Element.selectNodes(xpathQuery) 選擇匹配 XPath 表達式的結點集合
List<Attribute> list = root.selectNodes("//@出版社"); //獲取所有"出版社"屬性
for(Attribute attr : list){
System.out.println(attr.getValue());
}
}
}