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