Java学习Day17------XML、注解

XML

(1)作用
  a) 存储数据
  b) 传输数据
  c) 配置文件
(2)XML和HTML的区别
  a) HTML主要用于展示数据
  b) XML主要用于存储数据
(3)标签规则
  标签必须是包裹嵌套关系,不能是交叉嵌套关系

<student>
    <name>zhangsan</name>
    <age>18</age>
</student>

(4)注释

<!-- 这是注释信息,XML当中这样写  -->

解析DOM

(1)概述
在这里插入图片描述
(2)入门案例
  a) 解析步骤
    aa) 准备工作:导入 jar 文件,将jar文件添加到 模块当中
    bb) 准备工作:存在 xml 文件
    cc) 进行解析:获取到 Document 的对象
    dd) 进行解析:获取到 根标签
    ee) 进行解析:得到单独子标签 以及 属性 等信息
  b) 代码

<!-- game.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<lol>
    <hero id="1">
        <name>亚索</name>
        <age>30</age>
        <say>哈萨克</say>
    </hero>
    <hero id="2">
        <name>永恩</name>
        <age>32</age>
        <say>疾风亦有归途</say>
    </hero>
    <hero id="3">
        <name>瑞文</name>
        <age>26</age>
        <say>人在塔在</say>
    </hero>
</lol>
//英雄类
public class Hero {
    private int id;
    private String name;
    private int age;
    private String say;
    public Hero() {
    }
    public Hero(int id, String name, int age, String say) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.say = say;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    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;
    }
    public String getSay() {
        return say;
    }
    public void setSay(String say) {
        this.say = say;
    }
    @Override
    public String toString() {
        return "Hero{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", say='" + say + '\'' +
                '}';
    }
}

//测试类
public class Test {
    public static void main(String[] args) throws Exception {
        ArrayList<Hero> list = new ArrayList<>();
        String path = "dir\\game.xml";
        File f = new File(path);
        // --------
        // (1). 获取到 Document 的对象
        SAXReader reader = new SAXReader();
        Document document = reader.read(f);
        // (2). 获取到根标签
        Element rootElement = document.getRootElement();
        // (3). 获取到子标签,属性等信息
        List<Element> childElements = rootElement.elements();
        for (Element child : childElements) {
            String id = child.attribute("id").getValue();
            String name = child.element("name").getText();
            String age = child.element("age").getText();
            String say = child.element("say").getText();
            // --------
            //创建对象,将数据封装到对象当中,并且将对象封装到集合
            Hero hero = new Hero();
            hero.setId(Integer.parseInt(id));
            hero.setName(name);
            hero.setAge(Integer.parseInt(age));
            hero.setSay(say);
            list.add(hero);
        }
        // (4). 展示结果
        list.forEach(h-> System.out.println(h));
    }
}

约束

(1)DTD约束
  a) 引入方式
    aa) 本地引入 : dtd 文档是存在的
    bb) 内部引入 : dtd 文档是不存在, dtd 约束的语法是 写在了 XML 文件里面
    cc) 网络引入 : dtd 语法 定义在网上的, 通过网址引入
  b) 语法
    aa) 定义元素格式:
      <!ELEMENT 元素名称 元素类型>
    bb) 简单元素
      EMPTY: 表示标签体为空
      ANY: 表示标签体可以为空,也可以不为空
      PCDATA: 表示该元素的内容部分为字符串
    cc) 复杂元素 //直接写子元素名称
      多个子元素可以使用 “,” 或者 “|” 隔开。 “?” 零次或者多次
      ","表示定义子元素的顺序。 “+” 一次或者多次, “*” 零次或多次
      "|"表示子元素只能出现任意一个 如果不写则表示出现一次
    dd) 定义属性
      aaa) 格式:<!ATTLIST 元素名称 属性名称 属性的类型 属性的约束>
      bbb) 属性的类型
        CDATA类型: 普通的字符串
      ccc) 属性的约束
        #REQUIRED 必须的
        #IMPLIED 属性不是必须的
        #FIXED value 属性值是固定的
  c) 操作步骤
    aa) 新建一个 dtd 后缀名称的文件
    bb) 在 dtd 文件当中, 定义标签, 指明是 简单元素 还是 复杂元素
    cc) 在 xml 文件当中, 引入 dtd 约束
(2)Schema约束
  a) 概述
    Schema 本质上是一个 XML 文件, 他可以约束其他的XML, 也可以被其他XML文件约束。 Schema 约束文件比 DTD 的约束文件功能要更加的强大, 但是语法更为复杂
  b) 属性定义
在这里插入图片描述
  c) 案例

<!-- person.xsd -->
<?xml version="1.0" encoding="UTF-8"?>
<schema
        xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://suibian/javase"
        elementFormDefault="qualified">

    <!--  定义复杂元素 根标签 persons complexType复杂元素 sequence 顺序  -->
    <element name="persons">
        <complexType>
            <sequence>
                <!--  定义复杂元素 子标签 person complexType复杂元素 sequence 顺序  -->
                <element name="person">
                    <complexType>
                        <sequence>
                                <!--  定义简单元素,name 和 age 都是字符串类型 -->
                                <element name="name" type="string"></element>
                                <element name="age" type="string"></element>
                        </sequence>
                    </complexType>    
                </element>
            </sequence>
        </complexType>
    </element>
</schema>
<!-- person.xml -->
<?xml version="1.0" encoding="UTF-8"?>

<!-- 在根标签 persons 上面,引入 schema -->
<persons
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://suibian/javase"
        xsi:schemaLocation="http://suibian/javase ">
    <person>
        <name>zhangsan</name>
        <age>18</age>
    </person>
</persons>

注解

(1)概述:给编译器看的,用于解释说明程序。
(2)常见注解:

@Override                  方法重写
@FunctionalInterface       函数式接口
@since                     版本信息
@author                    作者信息
@SuppressWarnings("all")   压制所有警告

(3)本质
  java当中的注解本质上来说就是一个接口,但是这个接口是 继承了Annotation 的接口。注解当中的属性,实际上就是 该接口当中的抽象方法。
(4)特殊属性value
  如果我们在 注解当中,定义了 value 属性。 只有这一个 value 属性没有给出 默认值 (default),在使用注解的时候, 可以省略 value= 写法(如果在注解当中, 存在多个属性没有给出default属性值的情况,(其中包含有 value)那么value必须给出。)

例如:
    压制警告的注解。底层代码的写法:
    public @interface SuppressWarnings {
        String[] value();
    }

使用注解的时候,就可以这样写:
    @SuppressWarnings(value = "all")   //正确写法!
    @SuppressWarnings("all")   //也是正确写法! 可以省略 value=

(5)元注解
  a) 概述:给自定义注解,添加注解。添加的注解就叫做元注解。
  b) 常见元注解

元注解名称作用说明
@Target指定了注解能够在哪里使用
@Retention可以理解保留的时间(生命周期)
@Inherited表示修饰的自定义注解 可以被子类继承
@Documented表示该自定义注解,会出现在 API 文档里面

(6)案例
  a) 注解方法运行

//定义的注解: 指定元注解
@Target(ElementType.METHOD)   //作用在方法上面
@Retention(RetentionPolicy.RUNTIME) //存活在运行时阶段
public @interface ZhuJie {
}
//定义的人类
public class Person {
    @ZhuJie
    public void eat(){
        System.out.println("方法 eat...");
    }

    public void show(){
        System.out.println("方法 show...");
    }

    @ZhuJie
    public void work(){
        System.out.println("方法 work...");
    }
}

//测试类
public class Test {
    public static void main(String[] args) throws Exception{
        // (1). 获取到字节码对象,并且采用字节码对象去创建对象
        Class<?> clazz = Class.forName("com.it.Person");
        Constructor<?> c = clazz.getDeclaredConstructor();
        c.setAccessible(true);
        Object o = c.newInstance();

        // (2). 反射获取到所有的成员方法,判断该方法上面,是否添加注解
        Method[] methodArray = clazz.getDeclaredMethods();
        for (Method m : methodArray) {
            //判断是否添加了注解,如果添加注解,运行方法
            if (m.isAnnotationPresent(ZhuJie.class)){
                m.invoke(o);
            }
        }
    }
}

  b) 注解解析

//自定义注解
@Target(ElementType.TYPE)  //作用在类上
@Retention(RetentionPolicy.RUNTIME) //存活时间
public @interface ZhuJie {
    String className();
    String methodName();
}
//狗类
public class Dog {
    public void lookHome(){
        System.out.println("狗看家");
    }
}

//猫类
public class Cat {
    public void catchMouse(){
        System.out.println("猫抓老鼠");
    }
}


//测试类
@ZhuJie(className = "com.it.Dog",methodName = "lookHome")
public class Test {

    public static void main(String[] args) throws Exception{
        //通过注解添加位置的字节码对象,获取到注解的对象
        ZhuJie zhu = Test.class.getAnnotation(ZhuJie.class);
        String className = zhu.className();
        String methodName = zhu.methodName();
        // --------
        // (1). 获取字节码的对象, 通过字节码对象 创建对象
        Class<?> clazz = Class.forName(className);
        Constructor<?> c = clazz.getDeclaredConstructor();
        c.setAccessible(true);
        Object o = c.newInstance();

        // (2). 获取到方法的对象, 暴力反射, 准备调用方法
        Method m = clazz.getDeclaredMethod(methodName);
        m.setAccessible(true);
        m.invoke(o);
    }
}

  c) 综合案例(结合XML和注解)

<!-- peizhi.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<gen>
    <classname>com.itheima07.Teacher</classname>
    <methodname>teach</methodname>
</gen>
//当前的注解主要是用于控制访问的是哪一个XML文件
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyZhuJie {
    //采用value作为属性,使用注解的时候,可以省略
    String value();
}
//学生类
public class Student {
    public void study(){
        System.out.println("好好学习,天天睡觉");
    }
}

//老师类
public class Teacher {
    public void teach(){
        System.out.println("老铁,66666");
    }
}

@MyZhuJie("dir\\peizhi.xml")
public class Test {
    public static void main(String[] args) throws Exception{
        //解析注解(获取到路径)
        MyZhuJie zhuJie = Test.class.getAnnotation(MyZhuJie.class);
        String path = zhuJie.value();
        //解析XML(获取到类名和方法名)
        File f = new File(path);
        SAXReader sax = new SAXReader();
        Document document = sax.read(f);
        Element rootElement = document.getRootElement();
        String classname = rootElement.element("classname").getText();
        String methodname = rootElement.element("methodname").getText();
        //反射准备创建对象,调用方法
        Class<?> clazz = Class.forName(classname);
        Constructor<?> c = clazz.getDeclaredConstructor();
        c.setAccessible(true);
        Object o = c.newInstance();
        Method m = clazz.getDeclaredMethod(methodname);
        m.setAccessible(true);
        m.invoke(o);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值