1. XML简介
XML(EXtensible Markup Language),可扩展标记语言
特点
XML与操作系统、编程语言的开发平台无关
实现不同系统之间的数据交换
作用
数据交互
配置应用程序和网站
2. XML文档结构
<?xml version="1.0" encoding="UTF-8"?> <books> <!--图书信息 --> <book id="bk101"> <author>王珊</author> <title>.NET高级编程</title> <description>包含C#框架和网络编程等</description> </book> <book id="bk102"> <author>李明明</author> <title>XML基础编程</title> <description>包含XML基础概念和基本作用</description> </book> </books>
3. XML标签
XML文档内容由一系列标签元素组成
<元素名 属性名 = “属性值”>元素内容</元素名>
空元素:
<name> </name> <name></name> <name/>
属性值用双引号包裹
一个元素可以有多个属性
属性值中不能直接包含<、“、&(不建议:‘、>)
4. XML编写注意事项
所有XML元素都必须有结束标签
XML标签对大小写敏感
XML必须正确的嵌套
同级标签以缩进对齐
元素名称可以包含字母、数字或其他的字符
元素名称不能以数字或者标点符号开始
元素名称中不能含空格
5. 转义符
XML中的转义符列表
当元素中出现很多特殊字符时,可以使用CDATA节,如:
<description> <![CDATA[讲解了元素<title>以及</title>的使用]]> </description>
6. 解析XML技术
DOM
基于XML文档树结构的解析
适用于多次访问的XML文档
特点:比较消耗资源
SAX
基于事件的解析
适用于大数据量的XML文档
特点:占用资源少,内存消耗小
DOM4J
非常优秀的Java XML API
性能优异、功能强大
开放源代码
7. DTD
DTD即文档类型定义--Document Type Definition
使每个XML文件可以携带一个自身格式的描述
一个DTD文档可能包含如下内容:
元素的定义规则
元素之间的关系规则
属性的定义规则
编写DTD文档
<?xml version="1.0"?> <!DOCTYPE poem [ <!ELEMENT poem (author,title,content) > <!ELEMENT author (#PCDATA)> <!ELEMENT title (#PCDATA)> <!ELEMENT content (#PCDATA)> ]> <poem> <author>王维</author> <title>鹿柴</title> <content>空山不见人,但闻人语声。返景入深林,复照青苔上。 </content> </poem>
8. DOM解析XML
DOM介绍
文档对象模型(Document Object Model)
DOM把XML文档映射成一个倒挂的树
常用接口介绍
DOM解析包:org.w3c.dom
访问DOM树节点
DOM解析XML文件步骤:
创建解析器工厂对象
解析器工厂对象创建解析器对象
解析器对象指定XML文件创建Document对象
以Document对象为起点操作DOM树
phone.xml
<?xml version="1.0" encoding="GB2312"?> <PhoneInfo> <Brand name="华为"> <Type name="P9"/> </Brand> <Brand name="苹果"> <Type name="Iphone6"/> <Type name="Iphone7"/> </Brand> </PhoneInfo>
ParseXmlDemo.java
package com.liqinglin.test; 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; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.*; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.*; public class ParseXmlDemo { //收藏信息,xml对应的Document对象 private Document document; //获得DOM树,获得Document对象 public void getDom(){ //获得解析器工厂 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); try { //根据解析器工厂获得解析器 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); //解析器来解析XML文件获得Document对象 document = documentBuilder.parse("phone.xml"); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } //获取手机品牌及型号相关信息 public void showInfo(){ //以Document数起点,先拿到所有的Brand节点 NodeList brands = document.getElementsByTagName("Brand"); //遍历brands,从中拿到每一个Brand节点 for (int i = 0; i < brands.getLength(); i++){ Node node = brands.item(i); Element eleBrand = (Element) node; String brandName = eleBrand.getAttribute("name"); System.out.println(brandName); //继续查找,找每个Brands的子节点出来 NodeList types = eleBrand.getChildNodes(); for (int j = 0; j < types.getLength(); j++){ Node typeNode = types.item(j); //判断该子节点是否是元素节点 if(typeNode.getNodeType() == Node.ELEMENT_NODE){ Element typeEle = (Element) typeNode; System.out.println("\t" + typeEle.getAttribute("name")); } } } } //为XML文件添加元素 public void addEle(){ //(1)创建<Brand> Element brand = document.createElement("Brand"); //(2)为<Bradn>设置name属性取值为三星 brand.setAttribute("name", "三星"); Element type = document.createElement("Type"); type.setAttribute("name", "NOTE2"); //将Type作为Brand的子元素 brand.appendChild(type); //将Brand放到PhoneInfo中去 document.getElementsByTagName("PhoneInfo").item(0).appendChild(brand); } //保存XML文件(需要借助转换器 源:最新的dom树 --> 目的地:phone.xml,借助的输出流) public void saveXML(){ //转换器工厂 TransformerFactory factory = TransformerFactory.newInstance(); //设置缩进 factory.setAttribute("indent-number", 4); try { //获取转换器 Transformer transformer = factory.newTransformer(); //指定转换格式 transformer.setOutputProperty(OutputKeys.ENCODING, "GB2312"); transformer.setOutputProperty(OutputKeys.INDENT, "YES"); DOMSource source = new DOMSource(document); OutputStream out = new FileOutputStream("phone.xml"); StreamResult result = new StreamResult(new OutputStreamWriter(out, "GB2312")); transformer.transform(source, result); } catch (TransformerConfigurationException | FileNotFoundException e) { e.printStackTrace(); } catch (TransformerException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } //修改元素 public void updateEle(){ //获取所有的Brand NodeList brands = document.getElementsByTagName("Brand"); for(int i = 0; i < brands.getLength(); i++){ Node brand = brands.item(i); Element brandEle = (Element) brand; brandEle.setAttribute("id", i+""); } this.saveXML(); } //删除 华为手机 public void deleteEle(){ //获取所有的Brand NodeList brands = document.getElementsByTagName("Brand"); for(int i = 0; i < brands.getLength(); i++){ Node brand = brands.item(i); Element brandEle = (Element) brand; if(brandEle.getAttribute("name").equals("华为")){ brandEle.getParentNode().removeChild(brandEle); } } this.saveXML(); } public static void main(String[] args) { ParseXmlDemo parseXmlDemo = new ParseXmlDemo(); parseXmlDemo.getDom(); parseXmlDemo.addEle(); parseXmlDemo.showInfo(); parseXmlDemo.updateEle(); parseXmlDemo.deleteEle(); parseXmlDemo.saveXML(); } }
9. DOM4J
Document:定义XML文档
Element:定义XML元素
Text:定义XML文本节点
Attribute:定义了XML 的属性
……
Dom4jDemo.java
package com.liqinglin.test; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import java.io.*; import java.util.Iterator; public class Dom4jDemo { private Document document; //获得document对象 public void loadDocument(){ SAXReader saxReader = new SAXReader(); try { document = saxReader.read(new File("phone.xml")); } catch (DocumentException e) { e.printStackTrace(); } } //显示手机的品牌及型号 public void showInfo(){ //获取XML根节点 Element root = document.getRootElement(); //获取所有的<Brand> Iterator eleBrands = root.elementIterator(); while(eleBrands.hasNext()){ Element brand = (Element) eleBrands.next(); System.out.println(brand.attributeValue("name")); //获取所有的<Type> Iterator eleTypes = brand.elementIterator(); while(eleTypes.hasNext()){ Element type = (Element) eleTypes.next(); System.out.println("\t" + type.attributeValue("name")); } } } //增加新的手机信息 public void addNewPhone(){ //获取XML根元素 Element root = document.getRootElement(); //创建<Brand> Element eleBrand = root.addElement("Brand"); eleBrand.addAttribute("name", "三星"); //创建<Type> Element eleType = eleBrand.addElement("Type"); eleType.addAttribute("name", "SX123"); } //修改节点 public void updatePhone(){ Element root = document.getRootElement(); Iterator eleBrands = root.elementIterator(); int id = 0; while(eleBrands.hasNext()){ Element brand = (Element) eleBrands.next(); id++; brand.addAttribute("id", id+""); } this.saveXML(); } //删除节点 public void deletePhone(){ Element root = document.getRootElement(); Iterator eleBrands = root.elementIterator(); while(eleBrands.hasNext()){ Element brand = (Element) eleBrands.next(); if(brand.attributeValue("name").equals("华为")){ brand.getParent().remove(brand); } } this.saveXML(); } //修改xml文件 public void saveXML(){ OutputFormat format = OutputFormat.createPrettyPrint(); //format.setEncoding("GB2312"); XMLWriter writer = null; try { writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream("phone.xml")), format); writer.write(document); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally{ try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void main(String[] args) { Dom4jDemo dom4jDemo = new Dom4jDemo(); dom4jDemo.loadDocument(); dom4jDemo.addNewPhone(); dom4jDemo.updatePhone(); dom4jDemo.deletePhone(); dom4jDemo.saveXML(); dom4jDemo.showInfo(); } }