一、何爲數據解析java
二、xml解析node
三、Excel解析apache
四、json解析json
舉個栗子----若是不一樣的程序之間須要通訊,假如說A程序須要B程序作一件事,B程序說數組
我能夠作這件事,可是須要給我必須的數據。我才能作這件事。數據結構
咱們能夠用下面一副圖表示:app
在上面這幅圖中,兩個數據的傳輸都是有數據格式的。咱們要作的就是解析這種數據格式或者生成這種數據格式的數據dom
首先咱們先認識一下xml數據:xss
可擴展標記語言(英語:Extensible Markup Language,簡稱:XML),是一種標記語言。標記指計算機所能理解的信息符號,經過此種標記,計算機之間能夠處理包含各類信息的文章等。 -----by wikiide
接下來咱們看一個XML數據吧
<?xml version="1.0" encoding="UTF-8"?> <Students> <Student> <name java="初級">張三</name> <age>14</age> <fav>燙頭</fav> </Student> <Student> <name java="高級">李四</name> <age>16</age> <fav>玩遊戲</fav> </Student> </Students>
咱們能夠看到xml數據的格式,xml數據的第一行寫的是xml版本號和字符編碼集
它下面的字標籤都是成對出現的,這個xml能夠表示兩個對象。
在Java中xml解析的常見方式大體能夠分爲如下幾個
一、DOM解析----文本對象模型(Document Object Model) w3c標準
二、SAX解析---- 基於事務驅動的解析
三、JAXP SAX和DOM結合
四、JDOM 第三方開源項目 jdom-*.jar
五、DOM4J 第三方開源項目 dom4j-*.jar
在此,咱們主要講解一下java內置的SAX解析和DOM解析
原理:將整個xml文檔當作一顆樹,會將整個文檔一次性讀入內存中(適合於小型xml文件解析)
首先咱們先要了解如下DOM解析裏的一些名詞
Document對象:文檔對象 extends Node
Node對象:節點對象,全部節點類型的父接口包含元素/標籤、屬性、文本、註釋
Element:元素/標籤(extends Node)
Attr:屬性節點(extends Node)
Text:文本節點(extends Node)
ps:除文檔對象以外,其餘的都是節點對象
爲了更形象的解釋一下,請看以下圖:
XML解析的步驟大體可分爲:
一、 構建器工廠
二、構建器
三、xml文件-》document對象
四、節點內容解析
package com.demo.udp; import java.io.File; import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class DomParse { public static void parseXml(String xmlfile){ //建立一個document工廠實例 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); Document doc = null; try { //有document工廠實例構建一個documentBuilder對象 DocumentBuilder builder = factory.newDocumentBuilder(); //解析整個xml文件構建成一個Document對象 doc = builder.parse(new File(xmlfile)); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //獲取Document對象的根節點---->Students Element root = doc.getDocumentElement(); //根節點下找到全部的Student節點--->Student ps:這裏的NodeList不是集合,不能foreach遍歷 NodeList elelist = root.getElementsByTagName("Student"); for(int i =0 ;i<elelist.getLength();i++){ Node stunode = elelist.item(i); //因爲Node裏面沒有getElementsByTagName方法,因此只能經過向下強轉成Element才能找到子節點 if(stunode.getNodeType()==Node.ELEMENT_NODE){ Element stuele = (Element)stunode; Node name = stuele.getElementsByTagName("name").item(0); System.out.println("name:"+name.getTextContent()); //Node name2 = root.getElementsByTagName("name").item(i); //System.out.println(name2.getFirstChild().getNodeValue()); Node java = name.getAttributes().getNamedItem("java"); System.out.println("java:"+java.getNodeValue()); } } } public static void main(String[] args) { parseXml("Students.xml"); } }
XML的生成大體可分爲:
一、 構建器工廠
二、構建器
三、構造一個空的document樹-----數據結構爲樹。
四、構造節點對象(元素、屬性、文本)
五、設定節點之間的關係
六、轉換(doc對象-》xml文件)
6.1 轉換器工廠
6.2 轉換器對象
6.3 輸入源 doc對象-》Source對象 輸出源 xml文件-》Result對象
6.4 transform(Source對象,Result對象)
/** * 建立xml文件 */ public static void createXml(String xmlfile){ //要寫入的數據 Student student = new Student("張三",18,"LOL","學習"); Student student2 = new Student("李四", 19, "cs:go", "打遊戲"); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); Document doc = null; try { DocumentBuilder builder = factory.newDocumentBuilder(); //建立document對象 doc = builder.newDocument(); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } //建立根節點 Element students = doc.createElement("Students"); //建立元素節點 Element stu1 = doc.createElement("Student"); Element stu2 = doc.createElement("Student"); Element name1 = doc.createElement("name"); Element name2 = doc.createElement("name"); Element age1 = doc.createElement("age"); Element age2 = doc.createElement("age"); Element fav1 = doc.createElement("fav"); Element fav2 = doc.createElement("fav"); //設置節點的關係,構建成一顆樹 doc.appendChild(students); students.appendChild(stu1); students.appendChild(stu2); stu1.appendChild(name1); stu1.appendChild(age1); stu1.appendChild(fav1); stu2.appendChild(name2); stu2.appendChild(age2); stu2.appendChild(fav2); //給屬性節點與文本節點賦值 name1.setAttribute("java", student.getAlivable()); name2.setAttribute("java", student2.getAlivable()); name1.setTextContent(student.getName()); age1.setTextContent(student.getAge()+""); fav1.setTextContent(student.getFav()); name2.setTextContent(student2.getName()); age2.setTextContent(student2.getAge()+""); fav2.setTextContent(student2.getFav()); //講構建好的dom樹轉換成xml文件 transform(doc,xmlfile); System.out.println("XML生成完畢!"); } /** * 樹轉換方法 * @param doc * @param filename */ private static void transform(Document doc,String filename){ //構建轉換工廠 TransformerFactory factory = TransformerFactory.newInstance(); try { //建立轉換器對象 Transformer transformer = factory.newTransformer(); Source sourse = new DOMSource(doc); Result result = new StreamResult(new File(filename)); transformer.transform(sourse, result); } catch (TransformerConfigurationException e) { e.printStackTrace(); } catch (TransformerException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
生成的新xml文件格式以下:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <Students> <Student> <name java="學習">張三</name> <age>18</age> <fav>LOL</fav> </Student> <Student> <name java="打遊戲">李四</name> <age>19</age> <fav>cs:go</fav> </Student> </Students>
前面我有提到SAX解析是一種基於數據事物驅動的解析,意思就是這個解析式被動式的。
它不會本身主動去解析xml文件,而是從上往下解析,遇到的xml文件是什麼類型就執行相應的方法。
SAX解析中解析的規則須要是一個DefaultHandler的子類。這個子類中重寫的方法則是解析規則。
下面就寫一個實例來看看SAX解析的魅力吧:
package com.demo.udp; import java.io.IOException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; public class SAXParse { public static void start(String filePath){ SAXParserFactory factory = SAXParserFactory.newInstance(); try { SAXParser sax = factory.newSAXParser(); sax.parse(filePath, new MySax()); } catch (ParserConfigurationException | SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { start("Students.xml"); } }
package com.demo.udp; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class MySax extends DefaultHandler{ //標籤名字 private String tagname=""; @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub super.startDocument(); System.out.println("開啓SAX解析..."); } @Override public void endDocument() throws SAXException { // TODO Auto-generated method stub super.endDocument(); System.out.println("SAX解析結束"); } /** * 這個方法的參數依次爲----名稱空間(若是沒有是null),本地空間,若是沒有命名空間這個爲null,真實名稱,屬性 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // TODO Auto-generated method stub tagname = qName; super.startElement(uri, localName, qName, attributes); for(int i = 0 ;i<attributes.getLength();i++){ //輸出屬性 System.out.println(attributes.getQName(i)+":"+attributes.getValue(i)); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // TODO Auto-generated method stub super.endElement(uri, localName, qName); //每次結束後須要將tagname置爲空 tagname = ""; } /** * 接收元素中字符數據的通知參數依次爲-----解析出來的字符,字符數組中開始的位置,字符數組中使用的長度 */ @Override public void characters(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub super.characters(ch, start, length); String str = new String(ch, start, length); if(tagname.equals("name")||tagname.equals("age")||tagname.equals("fav")){ System.out.println(str); } } }
以上代碼中我忘了說明一下命名空間了
xml文件中存在一種命名空間的東西----XML命名空間(XML namespace,也譯做XML名稱空間、XML名字空間)用於在一個XML文檔中提供名字惟一的元素和屬性。
它至關於咱們java工程裏的包。命名空間是本身規定的,其它們的訪問範圍也是本身定義的。
命名空間的規則以下:
既然講了SAX的解析,那麼接下來說一下SAX生成xml文件吧!
一樣,更DOM生成xml文件同樣,也是須要裝換成xml文件
-------------------------我是分隔符---------------------------------------------
-----------------------主要類-------------------------
----------------------TransformerHandler的父類-------------------------------
package com.demo.udp; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.List; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; public class CreateXMLBySAX { public void createMySAX(List<Student> students){ try { //建立一個SAX工廠實例向下強轉 SAXTransformerFactory factory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); TransformerHandler handler = factory.newTransformerHandler(); Transformer tran = handler.getTransformer(); //設置轉換中實際輸出屬性 tran.setOutputProperty(OutputKeys.INDENT, "yes"); tran.setOutputProperty(OutputKeys.ENCODING, "gbk"); tran.setOutputProperty(OutputKeys.VERSION, "1.0"); StreamResult result = new StreamResult(new FileOutputStream(new File("Students2.xml"))); handler.setResult(result); //開始生成document handler.startDocument(); AttributesImpl atts = new AttributesImpl(); atts.clear(); //根節點 handler.startElement("", "", "Students", atts); for (Student student : students) { //每次循環以前都要清空屬性列表 atts.clear(); handler.startElement("", "", "Student", atts); //添加屬性 atts.addAttribute("", "", "java", "", student.getAlivable()); handler.startElement("", "", "name", atts); //爲name添加文本 handler.characters(student.getName().toCharArray(), 0, student.getName().length()); handler.endElement("", "", "name"); //這裏將屬性列表清空 atts.clear(); handler.startElement("", "", "age",atts); handler.characters((student.getAge()+"").toCharArray(), 0, (student.getAge()+"").length()); handler.endElement("", "", "age"); handler.startElement("", "", "fav", atts); handler.characters((student.getFav()+"").toCharArray(), 0, (student.getFav()+"").length()); handler.endElement("", "", "fav"); handler.endElement("", "", "Student"); } handler.endElement("", "", "Students"); handler.endDocument(); } catch (TransformerConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { List<Student> stu = new ArrayList<>(); Student student = new Student("張三", 19, "電影", "中級"); stu.add(student); CreateXMLBySAX createXMLBySAX = new CreateXMLBySAX(); createXMLBySAX.createMySAX(stu); System.out.println("xml生成完畢"); } }
SAX生成xml的代碼裏面的方法與解析xml用的不是同一個類中的方法,DefaultHandel中的這些方法是重寫了父類的這些方法的。
咱們這裏用的是從父類繼承過來的方法。
這裏的以start開頭的方法至關於xml中的節點頭部
這裏的以end開頭的方法至關於xml中的節點尾部
首先聲明一下Exlel解析須要用到的jar包
連接:https://pan.baidu.com/s/1MkCRGDLM6NU-bgqcHDGN6A
提取碼:s15e
咱們須要用到的jar包以下:
想解析一種數據類型咱們必須先了解這種數據類型的結構,咱們先看一下Excel的結構吧
在這裏咱們還要明確另外一個東西,因爲Microsoft公司的office在2007版本以前使用的是xls格式,2007版本及之後版本使用的是xlsx版本
因此咱們在解析以前要進行版本的判斷。(通常根據後綴名就能夠判斷版本了)
若是是以xls結尾的則須要使用HSSF若是是xlsx結尾的須要使用XSSF
package com.demo.poi; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class ExcelDemo { /** * xlsx文件解析 office2007及之後版本文件格式 * @param filepath */ public static void xlsxparse(String filepath){ try { XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(filepath)); for (int i = 0;i<wb.getNumberOfSheets();i++) { XSSFSheet sheet = wb.getSheetAt(i); if(sheet!=null){ for(int j=0;j<sheet.getLastRowNum();j++){ XSSFRow row = sheet.getRow(j); if(row!=null){ for(int k = 0;k<row.getLastCellNum();k++){ XSSFCell cell = row.getCell(k); if(cell!=null){ System.out.println(getValue(cell)); } } } } } } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { //從控制檯接受信息 InputStream in = System.in; BufferedReader br = new BufferedReader(new InputStreamReader(in)); String str = null; try { //讀取一行輸入 str = br.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } String trim = str.trim(); String[] split = trim.split("\\."); System.out.println(split.length); if(split[split.length-1].equals("xls")){ xlsparse(trim); }else if(split[split.length-1].equals("xlsx")){ xlsxparse(trim); } try { br.close(); in.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //xls轉換數據格式 private static String getValue(HSSFCell hssfRow) { if (hssfRow.getCellType() == hssfRow.CELL_TYPE_BOOLEAN) { return String.valueOf(hssfRow.getBooleanCellValue()); } else if (hssfRow.getCellType() == hssfRow.CELL_TYPE_NUMERIC) { return String.valueOf(hssfRow.getNumericCellValue()); } else { return String.valueOf(hssfRow.getStringCellValue()); } } // xlsx轉換數據格式 private static String getValue(XSSFCell xssfRow) { if (xssfRow.getCellType() == xssfRow.CELL_TYPE_BOOLEAN) { return String.valueOf(xssfRow.getBooleanCellValue()); } else if (xssfRow.getCellType() == xssfRow.CELL_TYPE_NUMERIC) { return String.valueOf(xssfRow.getNumericCellValue()); } else { return String.valueOf(xssfRow.getStringCellValue()); } } /** * xls文件解析 office2003版本文件格式 * @param filename */ public static void xlsparse(String filename){ try { HSSFWorkbook wb = new HSSFWorkbook(new FileInputStream(filename)); for (int i = 0;i<wb.getNumberOfSheets();i++) { HSSFSheet sheet = wb.getSheetAt(i); if(sheet!=null){ for(int j=0;j<sheet.getLastRowNum();j++){ HSSFRow row = sheet.getRow(j); if(row!=null){ for(int k = 0;k<row.getLastCellNum();k++){ HSSFCell cell = row.getCell(k); if(cell!=null){ System.out.println(getValue(cell)); } } } } } } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
以上是我學習數據解析的總結,若有錯誤,よろしくお願いします!