XML

什么是XML

  1. Extensible Markup Language(可扩展的标记语言)
  2. 他是一个语言,有自己的语法,和Java以及其他的编程无关
  3. “标记” 在文件中包含类似于张三 ,这种用尖括号括起来的叫标记,使用来标记数据的。标记可以嵌套,有包含、所属关系。XML是纯文本文档,它是由“标记+数据”组成
  4. 例如:
  1. 建立文件:clases.xml
    <类库>
<属性>

</ 属性>

< /类库>

XML 的作用

  1. 存储数据【以后数据库存储文件】
  1. 做配置文件【重点应用方式】

XML的语法

1、文档声明

  1. 一个格式化好的XML文档,应该有一个“文档声明”,不是必须有
  2. 文档声明格式:

2、XML的语法_元素(标签)

  1. 元素:也叫标记、标签。
  2. 标签分类
  1. 完整标签:有开始标签,和结束标签
    <name>张三</name>
  2. 单标签:只有开始标签,没有结束标签;单标签可以通过属性来记录数据
    <property name="id" value="it001"/>
  1. 标签的语法
  1. 标签名称可以包含大部分的字符,包括中文
  2. 标签里可以包括以下的符号:“、 _ - . ”
  3. 但只能以字母、下划线、冒号开头
  4. 标签的内容:
  1. 可以是“数据”
    <name>张三</name>
  2. 可以是子标签
  1. 区分大小写

3、属性:唯一的

  1. 一个标签中可以定义任意多个的“属性”,属性的作用:存储数据。
  2. 语法规则
  1. 一个标签可以定义0或者多个属性,属性名不能重名,用空格隔开
  2. 属性的格式:属性名=“属性值”属性值必须要用单引号或者双引号括起来
    (认为单引号或者双引号里的内容是数值)
  3. 属性,必须定义在开始标签中。

4、注释

5、转义字符

如果数据中包含大量的转义字符,编写时可读性不好。可以使用CDATA区来标志数据。

6、解析XML文档 两种方式

  1. DOM解析:一次性将整个文档读取到内存中,会将内部的各种标签已经属性、数据等信息全部封装到一个对象中。最终形成DOM对象,在DOM对象内容保留文档的结构信息。优点:内存中保留文档的结构进行修改(增加、修改、删除元素等修改)。缺点:如果文档很大,会占用内存。
  2. SAX解析:一次读取,解析一行,读取下一行,之前的信息会被丢掉。优点:速度快,缺点:没有文档结构,不能进行节点的增删改查。
  3. PULL解析:用于Android系统内容不的解析方式。类型于SAX。

7、解析器

  1. JAXP
  2. JDom
  3. Jsoup
  4. dom4j:第三方开发包,内部结合了DOM和SAX解析的方式

8、解析原理 是一个创建树的过程

XML文档读取到内存的过程:先创建一个DOM对象(Document);在创建一个节点Element(根元素)对象;创建子元素Element(节点)对象在根元素下面;创建属性(Attribute)对象在子节点对象下面;值(一般是String)对象在属性对象下面;

Document
     |--根元素【Element】
        |--子元素
            |--属性对象【Attribute】
                |--值对象
            |--子元素对象(Element)
                |--值对象
                |--子元素对象

9、XML文档读取步骤

准备工作:引入第三方工具包Dom4j.jar

  1. 创建SAXReader对象
  2. 对象对去XML文档,生成DOM树
  3. 获取根元素
  4. 获取到根元素后,利用它获得其他的子元素还有它自己在的属性(Attribute)

常用的方法:

1.public String getName():获取当前Element对象的”标签名”;

2.public List elements():获取当前Element对象下的所有子元素;

3.public List elements(String eleName):获取当前Element对象下的所有 eleName的子元素;

4.public String getText():获取当前Element对象的数据内容;

5.public String elementText(String eleName):获取当前Element对象的”eleName子元素的数据内容”;

代码练习

demo.xml

<?xml version="1.0" encoding="UTF-8"?>
<students>
            <student id = "it001">
                <name>章子怡</name>
                <age>18</age>
                <sex>女</sex>
            </student>
            <student id = "it002">
                <name>汪峰</name>
                <age>19</age>
                <sex>男</sex>
            </student>
            <student id = "it003">
                <name>撒贝宁</name>
                <age>20</age>
                <sex>男</sex>
            </student>

            <teacher id="001" name="teacher">
                <name>春春</name>
                <age>56</age>
                <sex>女</sex>
            </teacher>

            <teacher>
            </teacher>
</students>

MyVisitor.java

import org.dom4j.Attribute;
import org.dom4j.Element;
import org.dom4j.VisitorSupport;

public class MyVisitor extends VisitorSupport {

    //获取标签的对象的名字
    @Override 
    public void visit(Element e) {

        System.out.println(e.getName());
    }
    //获取标签属性的名字
    @Override
    public void visit(Attribute a) {
        System.out.println(a.getName());
    }
}

测试类 demo01.java
import java.io.File;
import java.util.Iterator;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * 解析demo.xml文档
 * 
 * @author YandeHu
 *
 */
public class Demo01 {

    private static final String Element = null;

    public static void main(String[] args) throws Exception {
        // 创建SAXreader对象
        SAXReader reader = new SAXReader();
        // 读取demo.xml文档 返回一个文档对象
        Document dom = reader.read(new File("demo.xml"));
        // 读取XML文档的根节点
        Element root = dom.getRootElement();
        // 获得根节点的名称
        String rootName = root.getName();
        System.out.println(rootName);
        // 利用根节点获得下面的子节点
        /**
         * 遍历子节点的两种方式
         */
        // 迭代器遍历子节点

        Iterator elr = root.elementIterator();// 遍历所有的子节点还可以遍历
        while (elr.hasNext()) {
            Element e = (Element) elr.next();
            String id = e.attributeValue("id");// 获取标签的属性值
            System.out.println("id=" + id);
            String age = e.elementText("age");// 获取标签<age>里的内容
            System.out.println("age=" + age);
            System.out.println(e.getName());// 获取节点的名字
            // System.out.println(e.getStringValue());//获取标签标记的数据
            System.out.println(e.getText());
        }

        /**
         * Visitor 是 GOF 设计模式之一。其主要原理就 是两种类互相保有对方的引用,并且一种作为 Visitor 去访问许多
         * Visitable。
         */
        System.out.println("=========Visitor==============");
        root.accept(new MyVisitor());

    }
}

10、XML约束

  1. DTD:对一些简单的XML文件进行约束
  2. Schema:对一些比较复杂的XML文档进行更加细致、广泛的约束。

XML约束可以约束:

  • 根元素下都可以出现哪些子元素
  • 元素出现的顺序、次数
  • 元素包含的属性
  • 元素中包含哪些子元素或者数据

DTD约束条件的引入

  1. 内部引入
  2. 引入外部(本地)
  3. 引入外部(网络)

Schema约束条件的引入

schema文档结构说明

练习:读取XML文件获取类的信息,利用反射创建对象

代码

student.xml

<?xml version="1.0" encoding="UTF-8"?>
<classes>
    <class className="com.day16.text.Student">
        <name>张三</name>
        <age>18</age>
    </class>
</classes>

Student类

public class Student {

    private String name;
    private int age;

    public Student() {
        super();
    }

    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }

}

RefiectDemo类 测试类

import java.io.File;
import java.lang.reflect.Constructor;
import java.util.Iterator;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class ReflectDemo {

    public static void main(String[] args) throws Exception {
        //编写方法 获取XML文档classname内容的方法 
        String s=getDom(new File("student.xml"));

        //利用反射创建实例
        Class<?> c = Class.forName(s);
        //获取类的构造方法
        Constructor<?> con = c.getConstructor(String.class,int.class);
        Object stu = con.newInstance("小明",23);
        System.out.println(stu);
    }

    public static String getDom(File file) throws Exception{
        //创建SAXreader对象
        SAXReader reader=new SAXReader();
        //读取XML文档
        Document dom = reader.read(file);
        //获取根节点
        Element root = dom.getRootElement();

        String value=null;
        //遍历根节点
        Iterator list = root.elementIterator();
        while(list.hasNext()){
            Element element = (Element) list.next();
            //获取<class>标签的属性值
            Attribute classname= element.attribute("className");
            value= classname.getValue();
        }

        return value;
    }
}

2017/11/1 17:32:39