XML

XML

1.XML概述

xml: extendsible markup language,可扩展的标记语言。其实就是一个文件,后缀为 .xml。

作用:

  • 可以用来保存数据

  • 可以用来做配置文件

  • 数据传输载体

2.文档声明

<?xml version="1.0" encoding="gbk" standalone="no" ?>
version : 解析这个xml的时候,使用什么版本的解析器解析
encoding : 解析xml中的文字的时候,使用什么编码来翻译
standalone  : no - 该文档会依赖关联其他文档 ,yes-- 这是一个独立的文档

默认文件保存的时候,使用的是GBK的编码保存,所以要想让我们的xml能够正常的显示中文,有两种解决办法:

  1. 让encoding也是GBK 或者 gb2312;
  2. 如果encoding是 utf-8 , 那么保存文件的时候也必须使用utf-8。

保存的时候见到的ANSI 对应的其实是我们的本地编码 GBK。为了通用,建议使用UTF-8编码保存,以及encoding 都是 utf-8。

3.元素定义(标签)

  1. 其实就是里面的标签, <> 括起来的都叫元素 。 成对出现。 如下:

  2. 文档声明下来的第一个元素叫做根元素 (根标签)

  3. 标签里面可以嵌套标签

  4. 空标签

    既是开始也是结束。 一般配合属性来用。

  5. 标签可以自定义。

    XML 命名规则:

    名称可以含字母、数字以及其他的字符
    名称不能以数字或者标点符号开始
    名称不能以字符 “xml”(或者 XML、Xml)开始
    名称不能包含空格

4.简单元素&复杂元素

  • 简单元素

元素里面包含了普通的文字

  • 复杂元素

元素里面还可以嵌套其他的元素

  • 属性的定义
定义在元素里面, <元素名称  属性名称="属性的值"></元素名称>
	<stus>
		<stu id="10086">
			<name>张三</name>
			<age>18</age>
		</stu>
		<stu id="10087">
			<name>李四</name>
			<age>28</age>
		</stu>
	</stus>

5.注释

与html注释一样:

不允许放置在文档的第一行,必须在文档声明的下面,文档声明必须在第一行。

6.非法字符

解析器会把"<"当作新元素的开始,因此不能这样写:

<message>if salary<1000</message>

需要把"<"替换为实体引用:

<message>if salary &lt; 1000</message>

"&" 也会产生错误,因为解析器会把该字符解释为字符实体的开始。严格地讲,在 XML 中仅有字符 "<"和"&" 是非法的。省略号、引号和大于号是合法的,但是把它们替换为实体引用是个好的习惯。

如果某段字符串里有过多的字符, 并且包含类似标签或关键字,不想让xml的解析器去解析。 那么可使用CDATA来包装。CDATA 指的是不应由 XML 解析器进行解析的文本数据,CDATA 部分中的所有内容都会被解析器忽略。不过这个CDATA 一般比较少看到,通常在服务器给客户端返回数据的时候。

CDATA 部分由 "" 结束:

<des><![CDATA[<a href="http://www.baidu.com">我爱黑马训练营</a>]]></des>

CDATA 部分不能包含字符串 "]]>"。也不允许嵌套的 CDATA 部分。

标记 CDATA 部分结尾的 "]]>" 不能包含空格或折行。

7.XML解析方式

  1. DOM(Document Object Model)

    采用树形结构的方式访问XML文档。可以修改或删除它们的内容,并创建新的元素。元素,它们的文本,以及它们的属性,都被认为是节点。

    • 优点

      允许应用程序对数据和结构做出更改;

      访问是双向的,可在任何时候在树中上下导航,获取和操作任意部分的数据。

    • 缺点

      通常需要加载整个XML文档来构造层次结构,消耗资源大。

  2. SAX(Simple API for XML)

    采取事件模型。

    • 优点

      无需等待所有数据都被处理,分析就能开始;

      可以在满足某个条件时停止解析,不必解析整个文档;

      只在读取数据时检查数据,不需保存在内存中;

      效率和性能较高,能解析大于系统内存的文档。

    • 缺点

      需要应用程序自己负责TAG的处理逻辑(如维护父子关系等),文档越复杂程序就越复杂;

      单向导航,无法定位文档层次,不支持XPath。

  3. JDOM(Java-based Document Object Model)

    目的是成为Java特定文档模型。

    • 优点

      使用具体类而不是接口,简化了API;

      大量使用了Java集合类,方便开发人员。

    • 缺点

      灵活性较差;

      性能较差。

  4. DOM4J(Document Object Model for Java)

    • 优点

      大量使用了Java集合类,方便开发人员;

      支持XPath;

      性能好。

    • 缺点

      大量使用了接口,API较为复杂。

  • 比较
    1. DOM4J性能最好,如果XML文档较大且不考虑可移植性,就采用DOM4J。
    2. JDOM和DOM性能较差,但可移植,如果文档较小建议用JDOM。
    3. SAX性能较好,如果需要及时处理数据而不需要保存数据则考虑SAX。

8.DOM4J用法

  • DOM4J基本用法
    1. 创建SaxReader对象
    2. 指定解析的xml
    3. 获取根元素
    4. 根据根元素获取子元素或孙元素
public static void main(String[] args) throws DocumentException, IOException {
        //1.创建SaxReader对象
        SAXReader sr=new SAXReader();
        //2.指定要解析的xml,获取文档对象
        Document document=sr.read(new File("D:\\IDEA.workspace\\Demo01\\test1\\src\\xmlFile\\stus.xml"));
        //3.获取根元素
        Element rootElement=document.getRootElement();
        System.out.println(rootElement.getName());//获得元素名称
        //4.遍历xml树
        //(1)枚举
        //枚举所有子节点
        for(Iterator i = rootElement.elementIterator();i.hasNext();){
            Element element=(Element) i.next();
            System.out.println(element.getName());    System.out.println(element.element("name").getText()+"\t"+element.element("age").getText());
        }
        //(2)枚举名称为stu2的节点
        for (Iterator i=rootElement.elementIterator("stu2");i.hasNext();){
            Element stu2=(Element)i.next();
        }
        //(3)枚举属性
        for (Iterator i=rootElement.attributeIterator();i.hasNext();){
            Attribute attribute=(Attribute) i.next();
            System.out.println(attribute);
        }
        //删除或增加节点
        //a.删除stu2节点中的address节点的province节点
        Element stu2Element=rootElement.element("stu2");
        Element addressElement=stu2Element.element("address");
        Element provinceElement=addressElement.element("province");
        addressElement.remove(provinceElement);
        //b.在stu2节点中增加一个name节点,文本为"jerry",属性值id为1
        //创建name节点
        Element newNameNode= DocumentHelper.createElement("name");
        //设置节点文本
        newNameNode.setText("jerry");
        //为name节点添加属性值
 newNameNode.add(DocumentHelper.createAttribute(newNameNode,"id","1"));
        //将该节点插入到stu节点中
        stu2Element.add(newNameNode);
        //将改动写入到xml
        XMLWriter writer=new XMLWriter(new FileWriter("D:\\IDEA.workspace\\Demo01\\test1\\src\\xmlFile\\stus.xml"));
        writer.write(document);
        writer.close();
    }
  • XPath支持

    DOM4J对XPath有良好的支持,如访问一个节点,可直接用XPath选择。

    步骤:

    1. 添加jar包依赖 jaxen-1.1-beta-6.jar;

    2. 在查找指定节点的时候,根据XPath语法规则来查找;

    3. 后续的代码与以前的解析代码一样。

    public static void main(String[] args) throws DocumentException, IOException {
            SAXReader sr=new SAXReader();
            Document document=sr.read(new File("D:\\IDEA.workspace\\Demo01\\test1\\src\\xmlFile\\stus.xml"));
            Element rootElement=document.getRootElement();
            //1.获取name节点
            Node node=rootElement.selectSingleNode("//name");
            //默认获取的为第一个name节点
            System.out.println(node.getText());
            //2.获取多个name节点
            List<Element> list=rootElement.selectNodes("//name");
            //这里的泛型可以写node,但最好写Element,因为获取的每一个name为Element
            for (Element e:list) {
                System.out.println(e.getText());
            }
        }
    

9.XML约束

如下的文档, 属性的ID值是一样的,这在生活中是不可能出现的。 并且第二个学生的姓名有好几个,一般也很少。那么怎么规定ID的值唯一, 或者是元素只能出现一次,不能出现多次? 甚至是规定里面只能出现具体的元素名字。

<stus>
	<stu id="10086">
		<name>张三</name>
		<age>18</age>
		<address>深圳</address>
	</stu>
	<stu id="10086">
		<name>李四</name>
		<name>李五</name>
		<name>李六</name>
		<age>28</age>
		<address>北京</address>
	</stu>
</stus>
  • DTD

    语法自成一派,出现较早,可读性差。

  1. 引入网络上的DTD

    <!--    文档类型  根标签名字 网络上的dtd   dtd的名称   dtd的路径-->
    <!DOCTYPE stus PUBLIC "//UNKNOWN/" "unknown.dtd">
    
  2. 引入本地的DTD

    <!-- 引入本地的DTD  : 根标签名字 引入本地的DTD  dtd的位置 -->
    <!-- <!DOCTYPE stus SYSTEM "stus.dtd"> -->
    
  3. 直接在XML里嵌入DTD的约束规则

    <!DOCTYPE stus [
        <!ELEMENT stus (stu)>
        <!ELEMENT stu (name,age)>
        <!ELEMENT name (#PCDATA)>
        <!ELEMENT age (#PCDATA)>
    ]>
    
    <!ELEMENT stus (stu)>  : stus 下面有一个元素 stu  , 但是只有一个
    <!ELEMENT stu (name , age)>  stu下面有两个元素 name  ,age  顺序必须name-age
    <!ELEMENT name (#PCDATA)> 
    <!ELEMENT age (#PCDATA)>
    <!ATTLIST stu id CDATA #IMPLIED> stu有一个属性 文本类型, 该属性可有可无
    
    元素的个数:
    		+ 一个或多个
    		*  零个或多个
    		? 零个或一个
    属性的类型定义:
    		CDATA : 属性是普通文字
    		ID : 属性的值必须唯一
    
    <!ELEMENT stu (name , age)>		按照顺序来 
    <!ELEMENT stu (name | age)>   两个中只能包含一个子元素
    
  • Schema

    其实就是一个xml , 使用xml的语法规则,xml解析器解析起来比较方便 , 是为了替代DTD 。
    但是Schema 约束文本内容比DTD的内容还要多,所以目前也没有真正意义上的替代DTD。

约束文档:
	<!-- xmlns  :  xml namespace : 名称空间 /  命名空间
	targetNamespace :  目标名称空间 。 下面定义的那些元素都与这个名称空间绑定上。 
	elementFormDefault : 元素的格式化情况。  -->

	<schema xmlns="http://www.w3.org/2001/XMLSchema" 
		targetNamespace="http://www.itheima.com/teacher" 
		elementFormDefault="qualified">
		<element name="teachers">
			<complexType>
				<sequence maxOccurs="unbounded">
					<!-- 这是一个复杂元素 -->
					<element name="teacher">
						<complexType>
							<sequence>
								<!-- 以下两个是简单元素 -->
								<element name="name" type="string"></element>
								<element name="age" type="int"></element>
							</sequence>
						</complexType>
					</element>
				</sequence>
			</complexType>
		</element>
	</schema>

实例文档:
	<?xml version="1.0" encoding="UTF-8"?>
	<!-- xmlns:xsi : 这里必须是这样的写法,也就是这个值已经固定了。
	xmlns : 这里是名称空间,也固定了,写的是schema里面的顶部目标名称空间
	xsi:schemaLocation : 有两段: 前半段是名称空间,也是目标空间的值 , 后面是约束文档的路径。
	 -->
	<teachers
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns="http://www.itheima.com/teacher"
		xsi:schemaLocation="http://www.itheima.com/teacher teacher.xsd"
	>
		<teacher>
			<name>zhangsan</name>
			<age>19</age>
		</teacher>
		<teacher>
			<name>lisi</name>
			<age>29</age>
		</teacher>
		<teacher>
			<name>lisi</name>
			<age>29</age>
		</teacher>
	</teachers>

名称空间的作用:在写元素的时候,可以指定该元素使用的是哪一套约束规则。

一个xml 可以引用多个schema约束。 但是只能引用一个DTD约束。

10.程序架构

  • C/S(client/server)

如QQ,微信。

优点:有一部分代码写在客户端, 用户体验比较好。

缺点:服务器更新,客户端也要随之更新,占用资源大。

  • B/S(browse/server)

如:网页游戏,web微信

优点:客户端只要有浏览器就可以,占用资源小,不用更新。

缺点:用户体验不佳。

posted @ 2020-10-17 09:50  ALiWang1123  阅读(208)  评论(0编辑  收藏  举报