/*
* Extensible Markup Language,可扩展标记语言,W3C开发 2000年1.0至今
* 存储带有结构性数据,一种数据存储格式
* 利用标签保存数据
* 开始标签&&结束标签,每一段标签描述一段数据,可以嵌套
* 对于人和计算机都非常友好
* 本质:就是一段字符串
* 应用主要两点:
* 1.在不同系统不同语言之间进行数据传输,具有跨平台特性
* 2.作为配置文件来使用。(properties,只能存储键值数据,没有层级结构)
*
* XML文件:
* 将符合xml语法格式的数据存储于一个文件中,通常后缀名为.xml,就得到了一个存储XML数据的
* XML文件。
* XML校验:浏览器除了可以处理和展示html格式的数据,还可以处理XML格式的数据,
* 如果浏览器可以打开XML格式数据,则正确,否则错误。
* 浏览器可以分析出XML其中的是数据结构。浏览器可以校验并显示问题所在。
*
* 二、XML语法
* 文档声明
* 元素
* 属性
* 注释
* CDATA区,特殊字符
* 处理指令(processing instruction)
*
*
* 1.文档声明格式:
* 通常是用来声明文档的属性的,必须放在文档的第一行,第一行不能有其他内容。
* 第一种写法:version是必须写的,用来声明实用的那个版本的XML,XML必须有且仅有一个根标签
* <?xml version="1.0" ?>
* 第二种写法:encoding 编码格式,用来解决文档乱码问题。
* <?xml version="1.0" encoding = "utf-8"?>
* 第三种写法:standalone 用来声明XML文档是否是一个独立文档,可以取值为yes表示是一个独立文档,
* 也可以取值no 表示依赖于其他文档
* <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
*
* 2.元素:一个标签就是一个XML元素
* <开始标签>标签体</结束标签>
* 如果一个标签内部,没有标签体+任何子标签,则该标签的标签体和子标签可以合并,为<a/>
* <a></a> ---> 简写为:<a/> --->自闭标签
* 一个标签可以嵌套若干子标签,但必须合理嵌套,不能交叉嵌套。
* 一个格式良好的XML文件有且仅有一个根标签,其他标签均为其子孙标签。
*
* 元素区分大小写,<P>与<p>不一样
* 不能以数字,标点符号,下划线_,xml(或XML,Xml)开头,
* 不能包含空格,
* 名称中间本能包含冒号(:);
* 3.属性:
* 一个xml元素可以具有0个或多个属性,属性是由属性名和属性值组成,属性名和属性值之间用=连接,
* 属性的值应该用单引号和双引号引起来。
* <? xml version="1.0" encoding="gbk" standalone="yes" ?>
* <中国 capital="北京" flag="五星红旗"></中国>
*
* 命名规范同上。
* 4.注释:
* <!--注释内容-->
* 注意:注释不能嵌套注释;
* 注释不能写在文档声明之前,因为文档声明必须处在整个文档最前面,之前不能有任何内容,
* 包括文档注释。
* 例1:
* <? xml version="1.0" encoding="gbk" standalone="yes" ?>
* <!--这是注释内容-->
* <中国 capital="北京" flag="五星红旗"></中国>
*
* 例2:
* <? xml version="1.0" encoding="gbk" standalone="yes" ?>
* <person>
* <name></name>
* <age></age>
* </person>
*
* 5.CDATA区,转义字符
* 转义字符:
* 如果文档中普通字符中包含了一些特殊字符,导致解析引擎解析出现问题,可以通过转义字符进行转义
* < --> <
* > --> >
* & --> &
* " --> "
* ' --> '
* 转义字符适用于需要转义内容比较少的情况,如果需要将一大段内容进行转义可以使用CDATA区进行。
* CDATA区:
* <![CDATA[
* 需要转义内容
* ]]>
* CDATA区适用于将一大段内容进行转义,好处可以处理一大段内容,不需要将内容中每一个内容进行
* 单一处理;
* 例如:
* <? xml version="1.0" encoding="gbk" standalone="yes" ?>
* <person>
* <name>张<name></name>
* <age>20</age>
* <code>
* <![CDATA[
* class Dog{
* public void eat(){
* String name = "狗仔";
* int i = 10;
* if(i<s){
* ....
* }
* }
* }
* ]]>
* </code>
* </person>
* 6.处理指令:xml中的处理指令用来通知解析引擎如何来解析xml 中的其他部分内容
* <?处理指令的名称 若干属性 ?>---很少用!
* html+css --html5--前端开发工程师
* xml+xslt+css(w3c想推广,但受到开发人员抵制,推广不开)
*
* 例如:
* <?xml-stylesheet href="" type="" standalone="no" ?>
* 例如:
* <? xml version="1.0" encoding="gbk" ?>
* <? xml-stylesheet type="text/css" href="1.css" ?>
* <country>
* <aa>中国</aa>
* <bb>美国</bb>
* <cc>法国</cc>
* <dd>俄罗斯</dd>
* </country>
*
* 1.css:
* aa{
* color:red;
* font-size:500px;
* }
*
* bb{
* color:blue;
* font-size:400px;
* }
* cc{
* color:green;
* font-size:200px;
* }
* dd{
* color:yellow;
* font-size:50px;
* }
*
*
* 三、xml约束
* 一个xml的写法可以用另一个文件来进行约束,这样的技术成为xml的约束技术
* 框架程序:框架如何运行有配置文件指定 太灵活了,产生问题。框架设计者写一个约束文件
* 应用:
* 1.xml约束技术可以用来约束xml文件写法,
* 2.写出xml文件也可以通过xml的约束文件进行校验
*
* 两种:--要求看的懂约束文件,不要求会写。(高级开发人员要会写)
* dtd 语法简单,容易学习,功能较弱
* schema 语法强大,可以实现语意级别的约束,语法复杂,学习成本高
*
* 1.DTD(Document Type Definition),全程为文档类型定义。
* DTD文件必须为utf-8编码,否则报错。
* 默认情况下,浏览器并没有开启dtd校验,不能用浏览器来校验xml是否符合dtd约束,
* 可以用JavaScript语法来校验。
* 其实还有更简单方法,我们的eclipse和Myeclipse都可以来进行dtd校验。
*
* 在xml中引入DTD:
* 引入外部文件:
* 可以在外部文件中写好dtd,在xml内部通过标签进行引入操作,
* 引入本地文件:
* <!DOCUMENT 根元素的名称 SYSTEM "dtd文件位置">
* 引入网络公共位置文件:
* <!DOCUMENT 文档的根结点 PUBLIC "DTD名称" "DTD文件的URL">
* 例如:
* <!DOCUMENT web-app PUBLIC
* "-//Sun Microsystems,Inc.//DTD Web Application 2.3//EN"
* "http://java.sun.com/dtd/web-app_2_3.dtd">
* 在xml文件内部定义:
* 在xml文档声明后通过语法直接将DTD写在xml中,
* <!DOCTYPE 根元素名称 [
* dtd内容
* ]>
*
* dtd语法:
* 元素声明
* <!ELEMENT 元素名称 元素的约束>
* 元素的约束:
* 存放类型、子元素的列表
* 存放类型:
* EMPTY:表示该元素的内部不能有任何其他内容
* ANY:表示该元素内部可以是任意内容
* 子元素的列表:表示该元素的内部按要求出现子元素。
* 子元素需要用小括号引起来,对于标签体有#PCDATA表示
* (#PCDATA):表示该元素中一般包含标签体。
* 如果子元素之间可以使用逗号","进行分割,表示子元素必须按顺序出现
* 如果子元素之间用竖线"|"进行分割,表示子元素只能出现其中之一。
* 另外可以使用数量词描述子元素出现的次数。
* +:表示1次到多次;
* *:表示0次到多次;
* ?:表示0次或1次;
* 还可以使用小括号进行组的操作
* 例如:
* <!ELEMENT MYFILE ((TITLE*,AUTHOR?,EMAIL)* | COMMENT) >
*
*
*
* 案例1:
* book.dtd:
* <!ELEMENT 书架 (书+)> 可以出现一次到多次 <!ELEMENT 书架 ANY>
* <!ELEMENT 书 (书名,作者,售价)> 注意标点符号为英文,注意空格一定要留,不能写在一起
* <!ELEMETT 书名 (#PCDATA)>
* <!ELEMENT 作者 (#PCDATA)>
* <!ELEMENT 售价 (#PCDATA)> 可以有标签体
*
* book.xml:
* xml文件:
* <?xml version="1.0" encoding="utf-8" standalone="no" ?>
* <!DOCTYPE 书架 SYSTEM "book.dtd" >
* <书架>
* <书>
* <书名>mysql编程指南</书名>
* <作者>郭德纲</作者>
* <售价>9.0元</售价>
* </书>
* <书>
* <书名>JavaScript入门案例</书名>
* <作者>本拉登</作者>
* <售价>8.0元</售价>
* </书>
* </书架>
*
* 案例2:
* <?xml version="1.0" encoding="utf-8" standalone="no" ?>
* <!DOCTYPE 书架 [
* <!ELEMENT 书架 (书+)> 可以出现一次到多次 <!ELEMENT 书架 ANY>
* <!ELEMENT 书 (书,作者,售价)>
* <!ELEMETT 书名(#PCDATA)>
* <!ELEMENT 作者(#PCDATA)>
* <!ELEMETN 售价(#PCDATA)> 可以有标签体
* <!ATTLIST 书
* 出版社 CDATA #REQUIRED
* 网址 CDATA #IMPLIED
* 出版范围 CDATA #FIXED "中国"
* 出版次数 CDATA "1"
* 种类(工具类|科技类|文学类|艺术|杂七杂八) #REQUIRED
* 书号 ID #REQUIRED
* >
* <!ENTUTY net "www.renmin.cn">
* ] >
* <书架>
* <书 出版社="人民出版社" 网址="&net;" 出版次数="2" 种类="工具类">
* <书名>mysql编程指南</书名>
* <作者>郭德纲</作者>
* <售价>9.0元</售价>
* </书>
* <书 出版社="北京邮电出版社"出版范围="">
* <书名>JavaScript入门案例</书名>
* <作者>本拉登</作者>
* <售价>8.0元</售价>
* </书>
* </书架>
*
*
*
* 属性声明
* <!ATTLIST 元素名
* 属性名1 属性类型 属性约束
* 属性名2 属性类型 属性约束
* ......
* >
* 属性类型:
* CDATA 表示为普通字符串类型,是一个普通的值
* ENUMERATED 表示属性是一个给定的枚举范围内
* ID 表示该属性作为ID来使用,ID的特点是:在整个文档范围内唯一。ID的值不能用数字开头。
* ENTITY(实体)
* 属性约束:
* #REQUIRED 必须存在的属性
* #IMPLIED 可选属性
* #FIXED 固定值,表示一个固定值的属性,可以不设定,
* 该属性默认就有且取值为给定的固定值,如果设定了,且
* 设定的值和给定的值不同,则报错。
* 默认值 表示该属性具有一个默认值,如果没有设置该属性,
* 该属性也有取值为这个默认值,如果设置了该属性,
* 该属性取值为设定的值。
*
* 实体的声明
* 所谓的实体就是将一大段的文字设定为实体,让其具有一个引用,在需要的地方可以通过引用
* 来使用这个实体定义的大段文本。
*
* 引用实体:在dtd中定义,在xml中使用的实体
* <!ENTITY 实体的名称 "I am a student" >
* <!ENTITY 实体的名称 实体的内容>
* 在xml中通过&实体名称; 使用实体
* 实体参数:在dtd中定义在dtd中使用的实体
* <!ENTITY % 实体名称 实体内容>
* 在dtd中通过 %实体名称; 使用实体
*
* 举例1:
* <!ENTITY % TAG_NAMES "姓名 | EMAIL | 电话 | 地址"> -->定义
*
* <!ELEMENT 个人信息 (%TAG_NAME; | 生日)> -->使用
* <!ELEMENT 客户信息 (%TAG_NAME; | 公司名)>
* 2.schema
*
* 四.xml解析
* 利用java程序操作xml中的数据
* 1.两种解析思想:
* dom方式解析:
*
* <? xml version="1.0" ?>
* <persons>
* <person id="110" gender="female">
* <name>marry</name>
* <age>18</age>
* </person>
* <person id="119" gender="male">
* <name>tom</name>
* <age>20</age>
* </person>
* </persons>
* 文档结构树,实现Node接口
* Document:dom:
* |_____Element:persons
* |______Element:person
* | |_________Arr:id=110
* | |_________Arr:gender=female
* | |_________Element:name
* | | |______Character:marry
* | |_________Element:age
* | |______Character:18
* |______Element:person
* |_________Arr:id=119
* |_________Arr:gender=male
* |_________Element:name
* | |______Character:tom
* |_________Element:age
* |______Character:20
* Dom:在解析时将读取整个文档,将文档中的每一个内容都用对象来表示,再利用对象之间的引用关系保存数据间的层级关系,
* 组成一棵文档结构树,利用操作这个树,就可以对整个文档进行增删改查的操作了。
*
* 缺点:
* 需要在解析时,将这个文档加载到内存中,耗费内存,如果xml格式的数据比较大,内存不足可能无法处理。
* 需要在解析时,一次性读取整个文档,会比较慢。
* 优点:
* 可以非常方便的对xml文档进行增删改查。
* 一次解析后,内存中就具有了文档树,以后不需要再重复解析。
sax方式解析: (工作时:用的更多,用于查询操作)
<? xml version="1.0" ?>__________ ______ ____________
<persons> | |解析器 |__|事件处理器 |
<person id="110"gender="female">| | | |文档解析开始()|
<name>marry</name> | | | |{....} |
<age>18</age> | | | |文档开始标签()|
</person> |__| | |{....} |
<person id="119" gender="male">| | | |发现标签体 () |
<name>tom</name> | | | |{.....} |
<age>20</age> | | | |发现结束标签()|
</person> | | | |{....} |
</persons>_______________________| |______| |文档解析结束()|
|{....} |
|____________|
*
* sax解析:
*通过扫描器扫描xml文档,在扫描过程中遇到内容出发事件处理器中对应的处理方法,
* 通过巧妙的设计事件处理其中的方法,可以和获取出需要处理的内容。
* 优点:
* 扫描方式不需要就爱那个这个文档加载到内存,占用内存较少。
* 不需要将整个文档都加载到整个内存,扫到哪里就有哪里的数据,速度比较快,
* 另外,一旦找到了需要的数据,解析就可以立即停止,后续的内容可以不用再扫描,非常灵活。
* 缺点:
* 每次需要数据就得重新扫描。
* 只能进行查询,不能对数据进行增,删,改的操作。
*
* 2.解析api
* sun--->jaxp原生的加入了j2se技术中。既有dom方式,也有sax方式,
* 不需要导入其他开发包直接就可以使用。但性能非常低,不好用。
* 开源组织提供:
* jdomo
* dom4 --->市面上最多,开源组织提供的解析api,api简单,性能高效,在很多地方都有所应用,内部集成了sax和dom
* pull --->sax解析方式的api,android原生解析方式,效率高,api简单
* ...
* xstream
* 3.dom4j(dom for java)
* 下载并导入开发包。官网下载。jar包,里面有很多包, 但主要用dom4j.jar包。看文档。dom4j默认dom方式
* 查询dom4j
* 解析book.xml:
*
* public class Dom4jDemo1{
* public static void main(String[] args){
* //1.导包,获取解析器
* //右键:new -->folder-->lib-->导包进来 -->右键:build path
* SAXReader reader = new SAXReader();
* //2.解析xml获取dom
* Document dom = reader.read("book.xml");
* //3.获取根结点
* Element root = dom.getRootElement();
* //4.获取第一本书:想要什么就点什么
* Element bookEle = root.element("书");
* //5.获取<书>中的<书名>
* Element bookNameEle = bookEle.element("书名");
* //6.获取<书名>标签体
* String text = bookNameEle.getText();
* System.out.println(text);
*
* }
* }
*
* 利用dom4j实现对xml的增删改查 (Creat Read Update Delete)
* public class Dom4jCRUD{
* @Test
* public void add(){
* //1.解析xml获取dom
* SAXReader reader = new SAXReader();
* Document dom = reader.read("book.xml");
* Element root = dom.getRootElement();
* //2.凭空创建<特价>结点
* Element price2Ele = DocumentHelper.createElement("特价");
* price2Ele.setText("0.9元");
* //3.找到父结点
* Element bookEle = root.element("书");
* //4.挂载上去
* bookEle.add(price2Ele);//目前只是在内存中操作dom树
* //5.将dom树写回到文件中
*
* //FileWriter writer =
* // new OutputStreamWriter(new FileOutputStream("book.xml"),"utf-8");
* //dom.write(writer);
* //writer.close();//不flush或close,文件会死在缓冲区
*
* XMLWriter writer =new
* WMLWriter(new FileOutputStream("book.xml"),
* OutputFormat.createPrettyPrint());
* writer.write(dom);
* writer.close();
*
* }
*
* @Test
* public void update() throw Exception{
* //1.解析xml获取dom
* SAXReader reader = new SAXReader();
* Document dom = reader.read("book.xml");
* Element root = dom.getRootElement();
* //2.获取需要修改结点
* Element price2Ele = root.element("书").element("特价");
* //3.修改内容
* pricesEle.setText("1.0元");
* //4.写回文件中
* XMLWriter writer = new
* XMLWriter(new FileOutputStream("book.xml"),
* OutputFormat.creatCompactFormat().createPrettyPrint());
*
* Writer.write(dom);
* writer.close();
* }
*
* @Test
* public void find()throw Exception{
* //1.解析xml获取dom
* SAXReader reader = new SAXReader();
* Document dom = reader.read("book.xml");
* Element root = dom.getRootElement();
* //2.获取第二本书的名字
* List<Element> list = root.elements("书");
* Element bookEle = list.get(1);
* Strings bookName = bookEle.element("书名");
* System.out.println(bookName);
* }
*
* @Test
* public void del(){
* //1.解析xml获取dom
* SAXReader reader = new SAXReader();
* Document dom = reader.read("book.xml");
* Element root = dom.getRootElement();
* //2.获取要删除的结点
* Element price2Ele = root.element("书").element("特价");
* //3.获取要删除结点的父结点,删除结点
* price2Ele.getParent().remove(price2Ele);
* //4.写出到文件中
* XMLReader writer = new XMLReader(new FileOutputStream("book.xml"),
* OutputFormat.createCompactFormat().createPrettyPrint());
*
* Writer.write(dom);
* writer.close();
* }
* @Test
* public void add2() throws Exception{
* //1.解析xml获取dom
* SAXReader reader = new SAXReader();
* Document dom = reader.read("book.xml");
* Element root = dom.getRootElement();
* //2.获取父结点
* Element bookEle = root.element("书");
* //3.凭空创建出结点
* Element price2Ele = DocumentHelper.createElement("特价");
* price2.Ele.setText("0.5元");
* //4.挂载
* List<Element> list = bookEle.elements();
* list.add(1,price2Ele);
* 5.写回
* XMLReader writer = new XMLReader(new FileOutputStream("book.xml"),
* OutputFormat.createCompactFormat().createPreetyPrint());
* Writer.write(dom);
* Wrirer.close();
*
* }
*
* @Test
* public void attr() throws Exception{
* ` //属性设置
* //1.解析xml获取dom
* SAXReader reader = new SAXReader();
* Document dom = reader.read("book.xml");
* Element root = dom.getRootElement();
*
* //2.获取父结点
* Element bookEle = root.element("书");
*
* //新增属性方法一:
* //3.凭空创建属性对象
* Attribute attr = DocumentHelper.creatAttribute(bookEle,"出版社","人民出版社");
* //4.挂载上去
* bookEle.add(attr);
*
*
* //---新增属性方法二:
* //bookEle.addAttribute("种类","工具书");//便捷方法,不是dom树的方法
* bookEle.setAttribute("种类","工具书");
*
* //---修改属性
* bookEle.setAttributeValue("种类","文学书");//方法过时,不推荐使用了
*
* //---查找属性值方式一:
* Attribute attr = bookEle.arrribute("出版社");
* System.out.println(attr.getName());
* System.out.println(attr.getValue());
*
* //---查找属性方式二:
* String v = bookEle.attributeValue("出版社");
* System.out.println(v);
*
* //---删除属性
* Attribute attr = bookEle.attribute("出版社");
* bookEle.remove(attr);
*
* //5.更新xml
XMLReader writer = new XMLReader(new FileOutputStream("book.xml"),
* OutputFormat.createCompactFormat().createPreetyPrint());
* Writer.write(dom);
* Wrirer.close();
* }
*
* }
*
*/
XML学习教程
最新推荐文章于 2022-01-27 16:28:18 发布