JavaSE——XML与JSON(语法格式、解析内容)
第6節(jié) XML與JSON
一、XML
1.1 XML簡介
XML全稱為可擴展標記語言(extensible Markup Language) 。
特性:
xml具有平臺無關性,是一門獨立的標記語言;
xml具有自我描述性。
用途:
網(wǎng)絡數(shù)據(jù)傳輸
數(shù)據(jù)存儲
配置文件(主要)
XML文件:
.XML文件是保存XML數(shù)據(jù)的一種方式,XML數(shù)據(jù)也可以以其他方式存在(如在內(nèi)存中構建XML數(shù)據(jù))。不要將XML語言狹隘的理解成XML文件。1.2 XML語法格式(重點)
1. XML文檔聲明(放在最開頭)<?xml version="1.0" encoding="UTF-8"?>2. 標記(元素、標簽、節(jié)點)XML文檔,由一個個的標記組成。語法:開始標記(開放標記):<標記名稱>結束標記(閉合標記):</標記名稱>標記名稱:自定義名稱,必須遵循一下命名規(guī)則:1.名稱可以包含字母、數(shù)字以及其他的字符2.名稱不能以數(shù)字或者標點符號開始3.名稱不能以字符"xml"(或者XML、Xml)開始4.名稱不能包含空格、不能包含冒號(:)5.名稱區(qū)分大小寫標記內(nèi)容:開始標記與結束標記之間,是標記的內(nèi)容。例如,我們通過標記,描述一個人名:<name>李偉杰</name>3. 一個XML文檔中,必須有且僅有一個根標記。正例:<names><name>張三</name><name>李四</name></names>反例:<name>張三</name><name>李四</name>4. 標記可以嵌套,但是不允許交叉正例:<person><name>李四</name><age>18</age></person>反例:<person> <name>李四<age></name>18</age></person>5. 標記的層級稱呼(子標記,父標記,兄弟標記,后代標記,祖先標記)例如:<persons><person><name>張三</name><length>180cm</length></person><person><name>李四</name><length>200cm</length></person></persons>name是person的子標記,也是person的后代標記,name是persons的后代標記,name是length的兄弟標記,person是name的父標記,persons是name的祖先標記。6. 標記名稱 允許重復(根標記只能有一個)7. 標記除了開始和結束,還有屬性。標記中的屬性,在標記開始時描述,由屬性名和屬性值組成。格式:在開始標記中,描述屬性;可以包含0-n個屬性,每一個屬性是一個鍵值對!同一個標記中的屬性名不允許重復,鍵與值之間使用等號連接,多個屬性之間使用空格分割,屬性值必須被引號括住。案例:<persons><person id="10001" group="1"><name>李四</name><age>18</age></person><person id="10002" group="1"><name>王五</name><age>19</age></person></persons>8. 注釋:注釋不能寫在文檔聲明之前注釋不能嵌套注釋格式:注釋開始:<!--注釋結束:-->案例:
描述一組圖書books,至少包含3本書,圖書book包含名稱name、info和屬性id:
<?xml version="1.0" encoding="UTF-8"?> <books><book id="10001"><name>三體</name><info>科幻小說</info></book><book id="10002"><name>平凡的世界</name><info>歷史小說</info></book><book id="10003"><name>百年孤獨</name><info>魔幻現(xiàn)實主義小說</info></book> </books>語法進階CDATA(了解)
CDATACDATA是不應該由XML解析器解析的文本數(shù)據(jù)。像"<"和"&"字符在XML元素中都是非法的。"<" 會產(chǎn)生錯誤,因為解析器會把該字符解釋為新元素的開始。"&" 會產(chǎn)生錯誤,因為解析器會把該字符解釋為字符實體的開始。某些文本,比如JavaScript代碼,包含大量的"<" 或 "&" 字符。為了避免錯誤,可以將腳本代 碼定義為 CDATA。CDATA部分中的所有內(nèi)容都會被解析器忽略。格式:由"<![CDATA["開始,由"]]>"結束。1.3 Java解析XML(掌握)
1.3.1 面試題
問: Java中有幾種XML解析方式 ? 分別是什么 ? 有什么樣的優(yōu)缺點 ?答: 四種.1. SAX解析解析方式是事件驅動機制 !SAX解析器, 逐行讀取XML文件解析 , 每當解析到一個標簽的開始/結束/內(nèi)容/屬性時,觸發(fā)事件.我們可以編寫程序在這些事件發(fā)生時, 進行相應的處理.優(yōu)點:1.分析能夠立即開始,而不是等待所有的數(shù)據(jù)被處理2.逐行加載,節(jié)省內(nèi)存.有助于解析大于系統(tǒng)內(nèi)存的文檔3.有時不必解析整個文檔,它可以在某個條件得到滿足時停止解析.缺點:1. 單向解析,無法定位文檔層次,無法同時訪問同一文檔的不同部分數(shù)據(jù)(因為逐行解析, 當解析第n行是, 第n-1行已經(jīng)被釋放了, 無法在進行操作了).2. 無法得知事件發(fā)生時元素的層次, 只能自己維護節(jié)點的父/子關系.3. 只讀解析方式, 無法修改XML文檔的內(nèi)容.2. DOM解析是用與平臺和語言無關的方式表示XML文檔的官方W3C標準,分析該結構通常需要加載整個文檔和內(nèi)存中建立文檔樹模型。程序員可以通過操作文檔樹, 來完成數(shù)據(jù)的獲取 修改 刪除等。優(yōu)點:1.文檔在內(nèi)存中加載, 允許對數(shù)據(jù)和結構做出更改。2.訪問是雙向的,可以在任何時候在樹中雙向解析數(shù)據(jù)。缺點:文檔全部加載在內(nèi)存中 , 消耗資源大。(可忽略)3. JDOM解析目的是成為Java特定文檔模型,它簡化與XML的交互并且比使用DOM實現(xiàn)更快。由于是第一個Java特定模型,JDOM一直得到大力推廣和促進。JDOM文檔聲明其目的是“使用20%(或更少)的精力解決80%(或更多)Java/XML問題”(根據(jù)學習曲線假定為20%)優(yōu)點:1.使用具體類而不是接口,簡化了DOM的API。2.大量使用了Java集合類,方便了Java開發(fā)人員。缺點:1.沒有較好的靈活性。2.性能不是那么優(yōu)異。4. DOM4J解析它是JDOM的一種智能分支。它合并了許多超出基本XML文檔表示的功能,包括集成的XPath支持、 XML Schema支持以及用于大文檔或流化文檔的基于事件的處理。它還提供了構建文檔表示的選項, DOM4J是一個非常優(yōu)秀的Java XML API,具有性能優(yōu)異、功能強大和極端易用使用的特點,同時它也是一 個開放源代碼的軟件。如今你可以看到越來越多的Java軟件都在使用DOM4J來讀寫XML。 目前許多開源項目中大量采用DOM4J , 例如:Hibernate。1.3.2 DOM4J解析XML(掌握)
步驟:
引入jar文件dom4j.jar;
創(chuàng)建一個指向XML文件的輸入流:
文檔對象:
指的是加載到內(nèi)存的整個XML文檔。
常用方法:
元素對象:
指的是XML文檔中的單個節(jié)點。
常用方法:
獲取節(jié)點名稱String getName();
獲取節(jié)點內(nèi)容String getText();
設置節(jié)點內(nèi)容String setText();
根據(jù)子節(jié)點的名稱,匹配名稱的第一個子節(jié)點對象Element element(String 子節(jié)點名稱);
獲取所有子節(jié)點對象List<Element> elements();
獲取節(jié)點的屬性值String attributeValue(String 屬性名稱);
獲取子節(jié)點的內(nèi)容String elementText(String 子節(jié)點名稱);
添加子節(jié)點Element addElement(String 子節(jié)點名稱);
添加屬性void addAttribute(String 屬性名, String 屬性值);
解析本地文件案例:
//1. 獲取文件的輸入流 FileInputStream fis = new FileInputStream("./src/com/kaikeba/coreclasslibrary/xmljson/demo1.xml"); //2. 創(chuàng)建XML讀取工具對象 SAXReader sr = new SAXReader(); //3. 通過讀取工具, 讀取XML文檔的輸入流 , 并得到文檔對象 Document doc = sr.read(fis); //4. 通過文檔對象 , 獲取文檔的根節(jié)點對象 Element root = doc.getRootElement(); //5. 通過根節(jié)點, 獲取所有子節(jié)點 List<Element> es = root.elements(); //6. 循環(huán)遍歷三個book for (Element e : es) {//1. 獲取id屬性值String id = e.attributeValue("id");//2. 獲取子節(jié)點name , 并獲取它的內(nèi)容String name = e.element("name").getText();//3. 獲取子節(jié)點info , 并獲取它的內(nèi)容String info = e.element("info").getText();System.out.println("id="+id+",name="+name+",info="+info); }結果如下:
books 10001 三體 科幻小說 ------------------------------ 10002 平凡的世界 歷史小說 ------------------------------ 10003 百年孤獨 魔幻現(xiàn)實主義小說 ------------------------------解析網(wǎng)絡文件案例:
String phone = "18516955565"; //1. 獲取到XML資源的輸入流 URL url = new URL("http://apis.juhe.cn/mobile/get?phone="+phone+"&dtype=xml&key=9f3923e8f87f1ea50ed4ec8c39cc9253"); URLConnection conn = url.openConnection(); InputStream is = conn.getInputStream(); //2. 創(chuàng)建一個XML讀取對象 SAXReader sr = new SAXReader(); //3. 通過讀取對象 讀取XML數(shù)據(jù),并返回文檔對象 Document doc = sr.read(is); //4. 獲取根節(jié)點 Element root = doc.getRootElement(); //5. 解析內(nèi)容 String code = root.elementText("resultcode"); if("200".equals(code)){Element result = root.element("result");String province = result.elementText("province");String city = result.elementText("city");if(province.equals(city)){System.out.println("手機號碼歸屬地為:"+city);}else{System.out.println("手機號碼歸屬地為:"+province+" "+city);} }else{System.out.println("請輸入正確的手機號碼"); }該網(wǎng)址下的XML內(nèi)容為:
解析的結果為:
手機號碼歸屬地為:北京1.4 XPATH解析XML
路徑表達式
通過路徑快速地查找一個或一組元素路徑表達式:1. / : 從根節(jié)點開始查找2. // : 從發(fā)起查找的節(jié)點位置 查找后代節(jié)點 ***3. . : 查找當前節(jié)點4. .. : 查找父節(jié)點5. @ : 選擇屬性 *屬性使用方式:[@屬性名='值'][@屬性名>'值'][@屬性名<'值'][@屬性名!='值']books: 路徑: //book[@id='1']//namebooksbook id=1nameinfobook id=2nameinfo使用步驟:
通過Node類的兩個方法,來完成查找: (Node是Document與Element的父接口)方法一://根據(jù)路徑表達式,查找匹配的單個節(jié)點Element e = selectSingleNode("路徑表達式");方法二://根據(jù)路徑表達式,查找匹配的節(jié)點列表List<Element> es = selectNodes("路徑表達式");案例如下所示:
String phone = "18313935565"; //1. 獲取到XML資源的輸入流 URL url = new URL("http://apis.juhe.cn/mobile/get?phone="+phone+"&dtype=xml&key=9f3923e8f87f1ea50ed4ec8c39cc9253"); URLConnection conn = url.openConnection(); InputStream is = conn.getInputStream(); //2. 創(chuàng)建一個XML讀取對象 SAXReader sr = new SAXReader(); //3. 通過讀取對象 讀取XML數(shù)據(jù),并返回文檔對象 Document doc = sr.read(is);Node node = doc.selectSingleNode("//company"); System.out.println("運營商:"+node.getText()); is.close();該網(wǎng)址下的XML內(nèi)容為:
解析的結果為:
聯(lián)通1.5 Java生成XML(熟悉)
使用步驟:
1. 通過文檔幫助器(DocumentHelper),創(chuàng)建空的文檔對象Document doc = DocumentHelper.createDocument();2. 通過文檔對象,向其中添加根節(jié)點Element root = doc.addElement("根節(jié)點名稱");3. 通過根節(jié)點對象root,豐富我們的子節(jié)點Element e = root.addElement("元素名稱");4. 創(chuàng)建一個文件輸出流,用于存儲XML文件FileOutputStream fos = new FileOutputStream("要存儲的位置");5. 將文件輸出流,轉換為XML文檔輸出流XMLWriter xw = new XMLWriter(fos);6. 寫出文檔xw.write(doc);7. 釋放資源xw.close();案例:
//1. 通過文檔幫助器, 創(chuàng)建空的文檔對象 Document doc = DocumentHelper.createDocument(); //2. 向文檔對象中, 加入根節(jié)點對象 Element books = doc.addElement("books"); //3. 向根節(jié)點中 豐富子節(jié)點 for(int i=0;i<1000;i++) {//向根節(jié)點中加入1000個book節(jié)點.Element book = books.addElement("book");//向book節(jié)點, 加入id屬性book.addAttribute("id", 1+i+"");//向book節(jié)點中加入name和info節(jié)點Element name = book.addElement("name");Element info = book.addElement("info");name.setText("蘋果"+i);info.setText("哈哈哈"+i); } //4. 創(chuàng)建文件的輸出流 FileOutputStream fos = new FileOutputStream("c:\\books.xml"); //5. 將文件輸出流 , 轉換為XML文檔輸出流 XMLWriter xw = new XMLWriter(fos); //6. 寫出XML文檔 xw.write(doc); //7. 釋放資源 xw.close(); System.out.println("代碼執(zhí)行完畢");XStream的使用(了解)
快速的將Java中的對象, 轉換為 XML字符串。
使用步驟:
創(chuàng)建XStream對象:XStream x = new XStream();
修改類生成的節(jié)點名稱(默認節(jié)點名稱為 包名.類名):x.alias("節(jié)點名稱", 類名.class);
傳入對象,生成XML字符串:String xml字符串 = x.toXML(對象);
案例:
Person p = new Person("張三", 18); XStream x = new XStream(); x.alias("person", Person.class); String xml = x.toXML(p); System.out.println(xml);結果如下:
<person><name>張三</name><age>18</age> </person>二、JSON
簡介:JSON全稱為JavaScript Object Notation (JS對象簡譜) , 是一種輕量級的數(shù)據(jù)交換格式。
2.1 JSON語法格式
2.1.1 對象格式
一本書書名簡介java:Class Book {private String name;private String info;get/set...}Book b = new Book();b.setName("金蘋果");b.setInfo(“種蘋果”);...js:var b = new Object();b.name = "金蘋果";b.info = "種蘋果";XML:<book><name>金蘋果</name><info>種蘋果</info></book>JSON:{"name":"金蘋果","info":"種蘋果"}一個對象,由一個大括號表示。括號中 通過鍵值對來描述對象的屬性(可以理解為,大括號中,包含的是一個個的鍵值對)格式:鍵與值之間使用冒號連接,多個鍵值對之間使用逗號分割;鍵值對的鍵要使用引號括起來(通常Java解析時, 鍵不使用引號會報錯. 而JS能正確解 析。)鍵值對的值,可以是JS中的任意類型的數(shù)據(jù)。2.1.2 數(shù)組格式
在JSON格式中可以與對象互相嵌套 [元素1,元素2...]案例:
{"name":"偉杰老師","age":18,"pengyou":["張三","李四","王二","麻子",{"name":"野馬老師","info":"像匹野馬一樣狂奔在技術鉆研的道路上"}],"heihei":{"name":"大長刀","length":"40m"} }2.2 Java解析JSON
主要內(nèi)容:
????將Java中的對象快速地轉換為JSON格式的字符串;
????將JSON格式的字符串,轉換為Java的對象。
2.2.1 Gson
將對象轉換為JSON字符串:
轉換JSON字符串的步驟:1. 引入JAR包2. 在需要轉換JSON字符串的位置編寫如下代碼即可:String json = new Gson().toJSON(要轉換的對象);案例:Book b = BookDao.find();String json = new Gson().toJson(b);System.out.println(json);將JSON字符串轉換為對象:
1. 引入JAR包 2. 在需要轉換Java對象的位置, 編寫如下代碼:對象 = new Gson().fromJson(JSON字符串,對象類型.class);案例:String json = "{\"id\":1,\"name\":\"金蘋果\",\"author\":\"李偉杰 \",\"info\":\"嘿嘿嘿嘿嘿嘿\",\"price\":198.0}";Book book = new Gson().fromJson(json, Book.class);System.out.println(book);2.2.2 FastJson
將對象轉換為JSON字符串:
轉換JSON字符串的步驟:1. 引入JAR包2. 在需要轉換JSON字符串的位置編寫如下代碼即可:String json=JSON.toJSONString(要轉換的對象);案例:Book b = BookDao.find();String json=JSON.toJSONString(b);System.out.println(json);將JSON字符串轉換為對象:
1. 引入JAR包 2. 在需要轉換Java對象的位置, 編寫如下代碼:類型 對象名=JSON.parseObject(JSON字符串, 類型.class);或List<類型> list=JSON.parseArray(JSON字符串,類型.class);案例:String json = "{\"id\":1,\"name\":\"金蘋果\",\"author\":\"李偉杰 \",\"info\":\"嘿嘿嘿嘿嘿嘿\",\"price\":198.0}";Book book = JSON.parseObject(json, Book.class);System.out.println(book);總結
以上是生活随笔為你收集整理的JavaSE——XML与JSON(语法格式、解析内容)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pytorch实现数据增强的原理
- 下一篇: OpenCV的数据类型——基础数据类型