1. 什么是XML?

XML 指可扩展标记语言(EXtensible Markup Language)
XML 是一种标记语言,很类似 HTML
XML 的设计宗旨是传输数据,而非显示数据
XML 标签没有被预定义。您需要自行定义标签。
XML 被设计为具有自我描述性。
XML 是 W3C 的推荐标准

2. 为什么使用XML?

我们没有XML这种语言之前,我们使用的是String作为两个程序之间的通讯!现在问题就来了,如果我们传输的是带有关系型结构的数据,String怎么表达呢?String对关系型数据不擅长,要是描述起来也难免会有歧义的时候!

HTML语言本身就有缺陷:

标记都是固定的,不能自定义。HTML语言中有什么标记就只能用什么标记
HTML标签本身就缺少含义 (tr标签里面什么内容都能放进去,不规范!)
HTML没有实现真正的国际化

3. XML的用途

①:配置文件(例子:Tomcat的web.xml,server.xml……),XML能够非常清晰描述出程序之间的关系
②:程序间数据的传输,XML的格式是通用的,能够减少交换数据时的复杂性!
③:充当小型数据库,如果我们的数据有时候需要人工配置的,那么XML充当小型的数据库是个不错的选择,程序直接读取XML文件显然要比读取数据库要快呢!

4. xml的技术架构

​ XML被设计为“什么都不做”,XML数据或XML文档只用于组织、存储数据,除此之外的数据生成、读取、传送、存取等等操作都与XML本身无关!

于是乎,想要操作XML,就需要用到XML之外的技术了:

为XML定规则:现在一般使用DTD或Schema技术,当然了Schema技术更为先进!
解析XML的数据:一般使用DOM或者SAX技术,各有各的优点
提供样式:XML一般用来存储数据的,但设计者野心很大,也想用来显示数据(但没人用XML来显示数据),就有了XSLT(eXtensiable Stylesheet Language Transformation)可扩展样式转换语言

5. XML语法

5.1 文档声明

XML声明放在XML的第一行
version —— 版本
encoding —— 编码
standalone–独立使用 —— 默认是no。standalone表示该xml是不是独立的。
如果是yes,则表示这个XML文档时独立的,不能引用外部的DTD规范文件;
如果是no,则该XML文档不是独立的,表示可以引用外部的DTD规范文档。
正确的文档声明格式,属性的位置不能改变!

<!-- 正确的文档声明格式,属性的位置不能改变! -->
<?xml version="1.0" encoding="utf-8" standalone="no"?>

  

5.2 元素

元素中需要值得注意的地方:

XML元素中的出现的空格和换行都会被当做元素内容进行处理
每个XML文档必须有且只有一个根元素
元素必须闭合
大小写敏感
不能交叉嵌套
不能以数字开头

XML的语法是规范的!不要随意乱写!

5.3 属性

属性是作为XML元素中的一部分的,命名规范也是和XML元素一样的!

<!-- 属性名是name,属性值是chinese -->
<china name="chinese"> </china>

  

5.4 CDATA

在编写XML文件时,有些内容可能不想让解析引擎解析执行,而是当作原始内容处理。

遇到此种情况,可以把这些内容放在CDATA区里,对于CDATA区域内的内容,XML解析程序不会处理,而是直接原封不动的输出。

 <![CDATA[     内容     ]]>

  

5.5 转义字符

对于一些单个字符,若想显示其原始样式,也可以使用转义的形式予以处理。

 

6. XML解析

6.1 XML解析方式有两种:

①:dom (Document Object Model) :文档对象模型,是W3C组织推荐解析XML的一种方式。

②:sax (Simple API For XML):它是XML社区的标准,几乎所有XML解析器都支持它!

6.2 XML解析操作

 

应用程序不是直接对XML文档进行操作的,而是由XML解析器对XML文档进行分析,然后应用程序通过XML解析器所提供的DOM接口或者SAX接口对分析结果进行操作,从而间接地实现了对XML文档的访问!

7. Java解析XML

xml文档中的数据

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<china>
<guangzhou >广州</guangzhou>
<shenzhen>深圳</shenzhen>
<beijing>北京</beijing>
<shanghai>上海</shanghai>
</china>

  

7.1 DOM解析

7.1.1 遍历

public class Main{
public static void main(String[] args) throws ParserConfigurationException , IOException, SAXException {
//API规范:需要用一个工厂来造解析器对象,先造了一个工厂
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); //获取解析器对象
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); //解析XML文档,得到了代表XML文档的Document对象!
Document document = documentBuilder.parse(new File("test.xml")); list(document);
} private static void list(Node node){
if(node.getNodeType() == Node.ELEMENT_NODE){
System.out.println(node.getNodeName());
} NodeList nodelist = node.getChildNodes(); for(int i = 0;i<nodelist.getLength();i++){
Node child = nodelist.item(i);
list(child);
}
}
}
/*
Output:
china
guangzhou
shenzhen
beijing
shanghai
*/

  

7.1.2 查询

private static void read(Document document){
NodeList nodelist = document.getElementsByTagName("a"); Node node = nodelist.item(0); String value = node.getTextContent(); System.out.println(value);
}
/*
Output:
广州
*/

  

7.1.3 增加

增加到XML文档中的最后

private static void add(Document document) throws TransformerException {
//创建需要增加的节点
Element element = document.createElement("hangzhou"); //向节点添加文本内容
element.setTextContent("杭州"); //得到需要添加节点的父节点
Node parent = document.getElementsByTagName("china").item(0); //把需要增加的节点挂在父节点下面去
parent.appendChild(element); //获取一个转换器它需要工厂来造,那么我就造一个工厂
TransformerFactory transformerFactory = TransformerFactory.newInstance(); //获取转换器对象
Transformer transformer = transformerFactory.newTransformer(); //把内存中的Dom树更新到硬盘中
transformer.transform(new DOMSource(document),new StreamResult("test.xml"));
}

  

增加到指定节点的前一个

private static void add2(Document document) throws TransformerException {
//获取到beijing节点
Node beijing = document.getElementsByTagName("beijing").item(0); //创建新的节点
Element element = document.createElement("guangxi"); //设置节点的文本内容
element.setTextContent("广西"); //获取到要创建节点的父节点,
Node parent = document.getElementsByTagName("china").item(0); //将guangxi节点插入到beijing节点之前!
parent.insertBefore(element, beijing); //将内存中的Dom树更新到硬盘文件中
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult("city.xml"));
}

  

7.1.4 删除

private static void delete(Document document) throws TransformerException {
//获取到beijing这个节点
Node node = document.getElementsByTagName("beijing").item(0); //获取到父节点,然后通过父节点把自己删除了
node.getParentNode().removeChild(node); //把内存中的Dom树更新到硬盘文件中
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(document),new StreamResult("test.xml"));
}

  

7.1.5 修改

private static void updata(Document document) throws TransformerException {
//获取到广州的结点
Node node = document.getElementsByTagName("guangzhou").item(0); node.setTextContent("广州你好"); //将内存中的Dom树更新到硬盘文件中
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(document),new StreamResult("test.xml"));
}

  

7.1.6 操作属性

private static void updataAttribute(Document document) throws TransformerException {
//获取到guangzhou节点
Node node = document.getElementsByTagName("guangzhou").item(0); //现在node节点没有增加属性的方法,所以我就要找它的子类---Element
Element guangzhou = (Element) node;
guangzhou.setAttribute("play","gzchanglong");
//如果要删除属性就用removeAttribute()方法 //将内存中的Dom树更新到硬盘文件中
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(document),new StreamResult("test.xml"));
}

  

7.2 dom4j解析

需要导入开发包

7.2.1 为什么要有dom4j?

dom缺点:比较耗费内存
sax缺点:只能对xml文件进行读取,不能修改,添加,删除
dom4j:既可以提高效率,同时也可以进行crud操作

7.2.2 获取Document对象

①:读取XML文件,获得document对象(这种最常用)

SAXReader reader = new SAXReader();
Document document = reader.read(new File("input.xml"));

  

②:解析XML形式的文本,得到document对象

String text = "<members></members>";
Document document=DocumentHelper.parseText(text);

  

③:主动创建document对象.

Document document =DocumentHelper.createDocument();

//创建根节点
Element root = document.addElement("members");

  

7.2.3 查询

XML文件

<?xml version="1.0" encoding="UTF-8" ?>
<person>
<name littleName="zk">xzk</name>
<age>20</age>
</person>

  

一般查询

public void read() throws DocumentException {
//获取到解析器
SAXReader saxReader = new SAXReader(); //获取到XML文件的流对象
InputStream inputStream = dom4j11.class.getClassLoader().getResourceAsStream("1.xml"); //通过解析器读取XML文件
Document document = saxReader.read(inputStream); //获取得到根节点
Element root = document.getRootElement(); //获取得到name节点
Element name = root.element("name"); //得到了name节点,就可以获取name节点的属性或者文本内容了!
String text = name.getText(); String attribute = name.attributeValue("littleName"); System.out.println("文本内容是:" + text);
System.out.println("属性内容是:" + attribute);
}
/*
Output:
文本内容是:xzk
属性内容是:zk
*/

  

多层结构的查询

//获取得到根节点
Element root = document.getRootElement(); //一层一层地获取到节点
Element element = root.element("guangdong").element("guangzhou").element("luogang"); String value = element.getText(); System.out.println(value);

  

7.2.4 增加

public void add() throws Exception {
//获取到解析器
SAXReader saxReader = new SAXReader(); //获取到XML文件的流对象
InputStream inputStream = dom4j11.class.getClassLoader().getResourceAsStream("1.xml"); //通过解析器读取XML文件
Document document = saxReader.read(inputStream); //创建出新的节点,为节点设置文本内容
Element newElement = DocumentHelper.createElement("name");
newElement.setText("ouzicheng"); //获取到根元素
Element root = document.getRootElement(); //把新创建的name节点挂在根节点下面
root.add(newElement); //创建带有格式的对象
OutputFormat outputFormat = OutputFormat.createPrettyPrint(); //设置编码,默认的编码是gb2312,读写的编码不一致,会导致乱码的!
outputFormat.setEncoding("UTF-8"); //创建XMLWriter对象
XMLWriter xmlWriter = new XMLWriter(new FileWriter("2.xml"), outputFormat); //XMLWriter对象写入的是document
xmlWriter.write(document); //关闭流
xmlWriter.close();
}

  

在指定的位置增加节点

//创建一个新节点
Element element = DocumentHelper.createElement("name");
element.setText("ouzciheng"); //获取得到person下所有的节点元素!
List list = document.getRootElement().elements(); //将节点添加到指定的位置上
list.add(1, element);

  

7.2.5 修改

//获取得到age元素
Element age = document.getRootElement().element("age");
age.setText("9999");

  

XMLWriter和获取Document对象的代码和前面的都是一样的

7.2.6 删除

//获取得到age节点
Element age = document.getRootElement().element("age"); //得到age节点的父节点,使用父节点的remove删除age节点!
age.getParent().remove(age);

  

XMLWriter和获取Document对象的代码和前面的都是一样的

最后

感谢你看到这里,看完有什么的不懂的可以在评论区问我,觉得文章对你有帮助的话记得给我点个赞,每天都会分享java相关技术文章或行业资讯,欢迎大家关注和转发文章!

【建议收藏】一份阿里大牛花了三天整理出来的XML学习笔记,写的非常详细的更多相关文章

  1. 花了三天整理,Spring Cloud微服务如何设计异常处理机制?还看不懂算我输

    前言 首先说一下为什么发这篇文章,是这样的.之前和粉丝聊天的时候有聊到在采用Spring Cloud进行微服务架构设计时,微服务之间调用时异常处理机制应该如何设计的问题.我们知道在进行微服务架构设计时 ...

  2. 新鲜出炉!花了三天整理的JVM复习知识点,面试突击必备!

    此次JVM知识点包含以下几个部分 1.类加载机制 2.jvm运行时数据区 3.java对象内存布局 4.jvm内存模型 5.垃圾回收机制 6.垃圾收集器 7.问题排查 一 类加载机制 主要说的部分是这 ...

  3. 解密国内BAT等大厂前端技术体系-携程篇(长文建议收藏)

    1 引言 为了了解当前前端的发展趋势,让我们从国内各大互联网大厂开始,了解他们的最新动态和未来规划.这是解密大厂前端技术体系的第四篇,前三篇已经讲述了阿里.腾讯.百度在前端技术这几年的技术发展. 这一 ...

  4. 解密国内BAT等大厂前端技术体系-美团点评之下篇(长文建议收藏)

    引言 在上篇中,我已经介绍了美团点评的业务情况.大前端的技术体系,其中大前端的技术全景图如下: 上篇重点介绍了工程化和代码质量的部分,工程化涵盖了客户端持续集成平台-MCI.全端监控平台-CAT.移动 ...

  5. 万字长文肝Git--全流程知识点包您满意【建议收藏】

    您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦. 本文将首先介绍在本地搭建GitLab服务,然后重点介绍Git的常用命令,Git的核心概念以及冲突处理,最后介绍Git与SVN的区别 干货满满,建议 ...

  6. web前端/移动端H5博客专家博客大全--值得收藏的前端技术大牛博客地址

    web前端/移动端H5博客专家博客大全--值得收藏的前端技术大牛博客地址   Huang Jie Blog .Com-前端开发 http://www.huangjieblog.com/?feed=rs ...

  7. 解密国内BAT等大厂前端技术体系-腾讯篇(长文建议收藏)

    1 引言 为了了解当前前端的发展趋势,让我们从国内各大互联网大厂开始,了解他们的最新动态和未来规划.这是解密大厂前端技术体系的第三篇,前两篇已经讲述了阿里和百度在前端技术这几年的技术发展.这一篇从腾讯 ...

  8. (转)python资料汇总(建议收藏)零基础必看

    摘要:没料到在悟空问答的回答大受欢迎,为方便朋友,重新整理汇总,内容包括长期必备.入门教程.练手项目.学习视频. 一.长期必备. 1. StackOverflow,是疑难解答.bug排除必备网站,任何 ...

  9. 解密国内BAT等大厂前端技术体系-美团点评之上篇(长文建议收藏)

    引言 进入2019年,大前端技术生态似乎进入到了一个相对稳定的环境,React在2013年发布至今已经6年时间了,Vue 1.0在2015年发布,至今也有4年时间了. 整个业界在前端框架不断迭代中,也 ...

随机推荐

  1. 微信小程序分类的实现

    微信小程序的分类功能思路 实现思路 1.把屏幕当成一个固定的盒子,然后把盒子分成两边,并让盒子的每一边都能够滚动. 2.通过将左侧边栏元素的id和右边内容的categoryId进行匹配,渲染展示相同i ...

  2. 这是2020年最强Python学习路线,从入门到精通!

    给大家整理的这套python学习路线图,按照此教程一步步的学习来,肯定会对python有更深刻的认识.或许可以喜欢上python这个易学,精简,开源的语言.全民学Python的话题铺天盖地,中国的Py ...

  3. count=count++

    count=count++ 的最终值是count =count,没加上1,该是啥是啥 count++ 的最终值是加一的值 注意: count = count ++ + 1 最终还是1

  4. 【总结】nginx基础

    一.nginx简介 1.什么是nginx? Nginx 是高性能的 HTTP 和反向代理的服务器,处理高并发能力是十分强大的,支持高达 50,000 个并发连接数.功能:反向代理,负载均衡,动静分离 ...

  5. NB-IoT成为3GPP后会有哪些优势

    NB-IoT无线接入的设计使用了很多LTE设计大的原则,并且得到了传统蜂窝网络和芯片组供应商的支持,使MBB取得了成功.NB-IoT采用与LTE(E-UTRA)相同的设计原则,尽管它使用单独的新载波, ...

  6. k8s部署之系统初始化(一)

    初始化 1.安装依赖包 yum -y install tree lrzsz nmap nc telnet vim wget lsof network-tools bash-completion bas ...

  7. C#+Arduino Uno 实现声控系统完全实施手册

    话不多说先上视频,一看就懂 另外可参考这里:https://www.cnblogs.com/dehai/p/4285749.html ,这个近6年前的帖子 程序结构 程序分成上位机(PC端)与下位机( ...

  8. 基于tensorflow的文本分类总结(数据集是复旦中文语料)

    代码已上传到github:https://github.com/taishan1994/tensorflow-text-classification 往期精彩: 利用TfidfVectorizer进行 ...

  9. Django做验证码登录

    验证码 关注公众号"轻松学编程"了解更多. 1.作用 在用户登录,注册以及一些敏感操作的时候,我们为了防止服务器被暴力请求,或爬虫爬取,我们可以使用验证码进行过滤,减轻服务器的压力 ...

  10. trie 树(字典树)

    目录 简述 trie 实现 前言 初始化 插入 检索 代码实现 例题 · 前缀统计 异或对 前言 贪心证明 代码实现 例题 · 最长异或值路径 可持久化 trie 树 简介 原理 代码实现 例题 总结 ...