1.XML简介 可扩展标记语言:意义+数据 标签可自行定义,具有自我描述性 纯文本表示,跨系统/平台/语言 W3C标准(1998年,W3C发布了XML1.0,包括几乎所有的Unicode字符) 1 2 3 4 5 <Student > <name > Tom</name > <age > 20</age > </Student >
XML结构 常规语法任何的起始标签都必须有一个结束标签 简化写法,例如,<name></name>可以写为<name/> 大小写敏感,如<name>和<Name>不一样 每个文件都要有一个根元素 标签必须按合适的顺序进行嵌套,不可错位 所有的特性都必须有值,且在值的周围加上引号 需要转义字符,如“<”需要用<代替 注释:<!-- 注释内容 --> XML扩展 DTD(Document Type Definition)定义 XML 文档的结构 使用一系列合法的元素来定义文档结构 可嵌套在xml文档中,或者在xml中引用 XML Schema(XSD,XML Schema Definition)定义 XML 文档的结构, DTD的继任者 支持数据类型,可扩展,功能更完善、强大 采用xml编写 XSL扩展样式表语言(eXtensible Stylesheet Language) XSL作用于XML,等同于CSS作用于HTML 内容XSLT: 转换 XML 文档 XPath: 在 XML 文档中导航 XSL-FO: 格式化XML文档 XML解析 树结构DOM: Document Object Model 文档对象模型,擅长(小规模)读/写 流结构SAX: Simple API for XML 流机制解释器(推模式),擅长读 Stax: The Streaming API for XML 流机制解释器(拉模式),擅长读 ,JDK 6 引入 2.XML解析(基于DOM) DOM 是 W3C 处理 XML 的标准 API直观易用 其处理方式是将 XML 整个 作为类似树结构 的方式读入内存 中以便操作及解析,方便修改 解析大数据量的 XML 文件,会遇到内存泄露 及程序崩溃的风险 1 2 3 4 <font > <name > Helvetica</name > <size > 36</size > </font >
graph TB
Document---ele[Element]
ele---tex[Text:whitespace]
ele---name[Element]
ele---tex2[Text:whitespace]
ele---size[Element]
ele---tex3[Text:whitespace]
name---tex4[Text:Helvetica]
size---tex5[Text:36] DOM类 DocumentBuilder 解析类,parse方法 Node 节点主接口,getChildNodes返回一个NodeList NodeList 节点列表,每个元素是一个Node Document 文档根节点 Element 标签节点元素 (每一个标签都是标签节点) Text节点 (包含在XML元素内的,都算Text节点) Attr节点(每个属性节点) 读取: 1. 自上而下遍历(DFS):1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();DocumentBuilder db = dbf.newDocumentBuilder();Document document = db.parse("pom.xml" );NodeList usersList = document.getChildNodes();System.out.println(usersList.getLength()); for (int i = 0 ; i < usersList.getLength(); i++) { Node users = usersList.item(i); NodeList userList = users.getChildNodes(); System.out.println("==" + userList.getLength()); for (int j = 0 ; j < userList.getLength(); j++) { Node user = userList.item(j); if (user.getNodeType() == Node.ELEMENT_NODE) { NodeList metaList = user.getChildNodes(); System.out.println("====" + metaList.getLength()); } } }
2. 根据名称进行搜索1 2 3 4 5 6 7 8 9 10 11 12 13 14 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();DocumentBuilder db = dbf.newDocumentBuilder();Document document = db.parse("pom.xml" );Element rootElement = document.getDocumentElement();NodeList nodeList=rootElement.getElementsByTagName("name" ); if (nodeList!=null ) { for (int i=0 ;i<nodeList.getLength();i++) { Element element = (Element)nodeList.item(i); System.out.println(element.getNodeName()+"=" +element.getTextContent()); } }
写入:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();Document document = dbBuilder.newDocument();if (document != null ) { Element docx = document.createElement("document" ); Element element = document.createElement("element" ); element.setAttribute("type" , "paragraph" ); element.setAttribute("alignment" , "left" ); Element object = document.createElement("object" ); object.setAttribute("type" , "text" ); Element text = document.createElement("text" ); text.appendChild(document.createTextNode("abcdefg" )); Element bold = document.createElement("bold" ); bold.appendChild(document.createTextNode("true" )); object.appendChild(text); object.appendChild(bold); element.appendChild(object); docx.appendChild(element); document.appendChild(docx); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource source = new DOMSource (document); File file = new File ("dom_result.xml" ); StreamResult result = new StreamResult (file); transformer.transform(source, result); }
3.XML解析(基于SAX) Simple API for XML
采用事件/流模型来解析 XML 文档,更快速、更轻量 有选择的解析和访问,不像 DOM 加载整个文档,内存要求较低 SAX 对 XML 文档的解析为一次性读取,不创建/不存储文档对象,很难同时访问文档中的多处数据 推模型。当它每发现一个节点就引发一个事件,而我们需要编写这些事件的处理程序 关键类:DefaultHandler 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 public class SAXReader { public static void main (String[] args) throws SAXException, IOException { XMLReader parser = XMLReaderFactory.createXMLReader(); BookHandler bookHandler = new BookHandler (); parser.setContentHandler(bookHandler); parser.parse("books.xml" ); System.out.println(bookHandler.getNameList()); } } class BookHandler extends DefaultHandler { private List<String> nameList; private boolean title = false ; public List<String> getNameList () { return nameList; } public void startDocument () throws SAXException { System.out.println("Start parsing document..." ); nameList = new ArrayList <String>(); } public void endDocument () throws SAXException { System.out.println("End" ); } public void startElement (String uri, String localName, String qName, Attributes atts) throws SAXException { if (qName.equals("title" )) { title = true ; } } public void endElement (String namespaceURI, String localName, String qName) throws SAXException { if (title) { title = false ; } } public void characters (char [] ch, int start, int length) { if (title) { String bookTitle = new String (ch, start, length); System.out.println("Book title: " + bookTitle); nameList.add(bookTitle); } } }
4.XML解析(基于Stax) Streaming API for XML
流模型中的拉模型 在遍历文档时,会把感兴趣的部分从读取器中拉出,不需要引发事件,允许我们选择性地处理节点 。这大大提高了灵活性,以及整体效率 两套处理API基于指针的API, XMLStreamReader 基于迭代器的API,XMLEventReader 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 public class StaxReader { public static void main (String[] args) { StaxReader.readByStream(); StaxReader.readByEvent(); } public static void readByStream () { String xmlFile = "books.xml" ; XMLInputFactory factory = XMLInputFactory.newFactory(); XMLStreamReader streamReader = null ; try { streamReader = factory.createXMLStreamReader(new FileReader (xmlFile)); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (XMLStreamException e) { e.printStackTrace(); } try { while (streamReader.hasNext()) { int event = streamReader.next(); if (event == XMLStreamConstants.START_ELEMENT) { if ("title" .equalsIgnoreCase(streamReader.getLocalName())) { System.out.println("title:" + streamReader.getElementText()); } } } streamReader.close(); } catch (XMLStreamException e) { e.printStackTrace(); } } public static void readByEvent () { String xmlFile = "books.xml" ; XMLInputFactory factory = XMLInputFactory.newInstance(); boolean titleFlag = false ; try { XMLEventReader eventReader = factory.createXMLEventReader(new FileReader (xmlFile)); while (eventReader.hasNext()) { XMLEvent event = eventReader.nextEvent(); if (event.isStartElement()) { StartElement start = event.asStartElement(); String name = start.getName().getLocalPart(); if (name.equals("title" )) { titleFlag = true ; System.out.print("title:" ); } Iterator attrs = start.getAttributes(); while (attrs.hasNext()) { Attribute attr = (Attribute) attrs.next(); } } if (event.isCharacters()) { String s = event.asCharacters().getData(); if (null != s && s.trim().length() > 0 && titleFlag) { System.out.println(s.trim()); } } if (event.isEndElement()) { EndElement end = event.asEndElement(); String name = end.getName().getLocalPart(); if (name.equals("title" )) { titleFlag = false ; } } } eventReader.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (XMLStreamException e) { e.printStackTrace(); } } }
5.JSON简介 JavaScript Object Notation, JS 对象表示法 是一种轻量级的数据交换格式 类似XML,更小、更快、更易解析 最早用于Javascript中,容易解析,最后推广到全语言 尽管使用Javascript语法,但是独立于编程语言 JSONObject和JSONArray 名称/值对。如"firstName":“John” JSON数组 Java的JSON处理 org.json:JSON官方推荐的解析类 GSON:Google出品基于反射,可以实现JSON对象、JSON字符串和Java对象互转 Jackson:号称最快的JSON处理器 Json主要用途 JSON生成 JSON解析 JSON校验 和Java Bean 对象进行互解析具有一个无参的构造函数 可以包括多个属性,所有属性都是private 每个属性都有相应的Getter/Setter方法 Java Bean用于封装数据,又可称为POJO(Plain Old Java Object) org.json 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 public static void main (String[] args) { testJsonObject(); testJsonFile(); } public static void testJsonObject () { Person p = new Person (); p.setName("Tom" ); p.setAge(20 ); JSONObject obj = new JSONObject (); obj.put("name" , p.getName()); obj.put("age" , p.getAge()); System.out.println("name: " + obj.getString("name" )); System.out.println("age: " + obj.getInt("age" )); } public static void testJsonFile () { File file = new File ("books.json" ); try (FileReader reader = new FileReader (file)) { int fileLen = (int ) file.length(); char [] chars = new char [fileLen]; reader.read(chars); String s = String.valueOf(chars); JSONObject jsonObject = new JSONObject (s); JSONArray books = jsonObject.getJSONArray("books" ); List<Book> bookList = new ArrayList <>(); for (Object book : books) { JSONObject bookObject = (JSONObject) book; Book book1 = new Book (); book1.setAuthor(bookObject.getString("author" )); book1.setYear(bookObject.getString("year" )); book1.setTitle(bookObject.getString("title" )); book1.setPrice(bookObject.getInt("price" )); book1.setCategory(bookObject.getString("category" )); bookList.add(book1); } for (Book book : bookList) { System.out.println(book.getAuthor() + ", " + book.getTitle()); } } catch (Exception e) { e.printStackTrace(); } }
GSON 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public static void main (String[] args) { testJsonObject(); testJsonFile(); } public static void testJsonObject () { Person p = new Person (); p.setName("Tom" ); p.setAge(20 ); Gson gson = new Gson (); String s = gson.toJson(p); System.out.println(s); Person p2 = gson.fromJson(s, Person.class); System.out.println(p2.getName()); System.out.println(p2.getAge()); JsonObject json = gson.toJsonTree(p).getAsJsonObject(); System.out.println(json.get("name" )); System.out.println(json.get("age" )); } public static void testJsonFile () { Gson gson = new Gson (); File file = new File ("books2.json" ); try (FileReader reader = new FileReader (file)) { List<Book> books = gson.fromJson(reader, new TypeToken <List<Book>>() { }.getType()); for (Book book : books) { System.out.println(book.getAuthor() + ", " + book.getTitle()); } } catch (Exception e) { e.printStackTrace(); } }
Jackson 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public static void main (String[] args) throws Exception { testJsonObject(); testJsonFile(); } static void testJsonObject () throws IOException { ObjectMapper om = new ObjectMapper (); Person p = new Person (); p.setName("Tom" ); p.setAge(20 ); String jsonStr = om.writeValueAsString(p); System.out.println(jsonStr); Person p2 = om.readValue(jsonStr, Person.class); System.out.println(p2.getName()); System.out.println(p2.getAge()); JsonNode node = om.readTree(jsonStr); System.out.println(node.get("name" ).asText()); System.out.println(node.get("age" ).asText()); } static void testJsonFile () throws IOException { ObjectMapper om = new ObjectMapper (); File json2 = new File ("books2.json" ); List<Book> books = om.readValue(json2, new TypeReference <List<Book>>(){}); for (Book book : books) { System.out.println(book.getAuthor()); System.out.println(book.getTitle()); } }
JSON vs XML 都是数据交换格式,可读性强,可扩展性高 大部分的情况下,JSON更具优势(编码简单,转换方便) JSON字符长度一般小于XML,传输效率更高 XML更加注重标签和顺序 JSON会丢失信息