Java:XML&约束&注解

一、xml

1.概述

  • XML的全称为(EXtensible Markup Language),是一种可扩展的标记语言
  • 标记语言: 通过标签来描述数据的一门语言(标签有时我们也将其称之为元素)
  • 可扩展:标签的名字是可以自定义的,XML文件是由很多标签组成的,而标签名是可以自定义的
  • 作用
    • 用于进行存储数据和传输数据
    • 作为软件的配置文件
  • 作为配置文件的优势
    • 可读性好
    • 可维护性高

2.标签规则

  • 标签由一对尖括号和合法标识符组成

    <student>
    
  • 标签必须成对出现

    <student> </student>
    前边的是开始标签,后边的是结束标签
    
  • 特殊的标签可以不成对,但是必须有结束标记

    <address/>
    
  • 标签中可以定义属性,属性和标签名空格隔开,属性值必须用引号引起来

    <student id="1"> </student>
    
  • 标签需要正确的嵌套

    这是正确的: <student id="1"> <name>张三</name> </student>
    这是错误的: <student id="1"><name>张三</student></name>
    

3、语法规则

  • 语法规则

    • XML文件的后缀名为:xml

    • 文档声明必须是第一行第一列

      <?xml version=“1.0” encoding=“UTF-8” standalone=“yes”?>
      version:该属性是必须存在的
      encoding:该属性不是必须的

      打开当前xml文件的时候应该是使用什么字符编码表(一般取值都是UTF-8)
      

      standalone: 该属性不是必须的,描述XML文件是否依赖其他的xml文件,取值为yes/no

    • 必须存在一个根标签,有且只能有一个

    • XML文件中可以定义注释信息

    • XML文件中可以存在以下特殊字符

      &lt; < 小于
      &gt; > 大于
      &amp; & 和号
      &apos; ' 单引号
      &quot; " 引号
      

二、约束

  • 什么是约束
    用来限定xml文件中可使用的标签以及属性

  • 约束的分类

    • DTD
    • schema
  • schema和dtd的区别

    1. schema约束文件也是一个xml文件,符合xml的语法,这个文件的后缀名.xsd
    2. 一个xml中可以引用多个schema约束文件,多个schema使用名称空间区分(名称空间类似于java包名)
    3. dtd里面元素类型的取值比较单一常见的是PCDATA类型,但是在schema里面可以支持很多个数据类型
    4. schema 语法更加的复杂

三、DTD

1、 编写DTD约束

  • 步骤

    1. 创建一个文件,这个文件的后缀名为.dtd
    2. 看xml文件中使用了哪些元素
      <!ELEMENT> 可以定义元素
    3. 判断元素是简单元素还是复杂元素
      简单元素:没有子元素。
      复杂元素:有子元素的元素;
    <!ELEMENT persons (person)>
    <!ELEMENT person (name,age)>
    <!ELEMENT name (#PCDATA)>
    <!ELEMENT age (#PCDATA)>
    

2、引入DTD约束

  • 引入DTD约束的三种方法
    • 引入本地dtd
      <!DOCTYPE 根元素名称 SYSTEM ‘DTD文件的路径'>

    • 在xml文件内部引入
      <!DOCTYPE 根元素名称 [ dtd文件内容 ]>

    • 引入网络dtd
      <!DOCTYPE 根元素的名称 PUBLIC "DTD文件名称" "DTD文档的URL">

3、DTD语法

定义元素

定义一个元素的格式为:<!ELEMENT 元素名 元素类型>

  • 简单元素:
    1. EMPTY: 表示标签体为空
    2. ANY: 表示标签体可以为空也可以不为空
    3. PCDATA: 表示该元素的内容部分为字符串
  • 复杂元素:
    1. 直接写子元素名称. 多个子元素可以使用","或者"|"隔开;
    2. ","表示定义子元素的顺序 ; "|": 表示子元素只能出现任意一个
    3. "?"零次或一次, "+"一次或多次, "*"零次或多次;如果不写则表示出现一次
![04_schema约束介绍.png](https://upload-images.jianshu.io/upload_images/1969836-6ee53b881193688c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) DTD语法定义元素.png
定义属性

定义一个属性的格式为:<!ATTLIST 元素名称 属性名称 属性的类型 属性的约束>

  • 属性的类型:
    CDATA类型:普通的字符串
  • 属性的约束:
    1. REQUIRED: 必须的

    2. IMPLIED: 属性不是必需的

    3. FIXED value:属性值是固定的

    <!ELEMENT persons (person+)>
    <!ELEMENT person (name,age)>
    <!ELEMENT name (#PCDATA)>
    <!ELEMENT age (#PCDATA)>
    <!ATTLIST person id CDATA #REQUIRED>

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE persons SYSTEM 'persondtd.dtd'>

    <persons>
        <person id="001">
            <name>张三</name>
            <age>23</age>
        </person>

        <person id = "002">
            <name>张三</name>
            <age>23</age>
        </person>
    </persons>

四、schema约束

1、编写schema约束

schema约束编写.png
<?xml version="1.0" encoding="UTF-8" ?>
    <schema
        xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.itheima.cn/javase"
        elementFormDefault="qualified"
    >

        <!--定义persons复杂元素-->
        <element name="persons">
            <complexType>
                <sequence>
                    <!--定义person复杂元素-->
                    <element name = "person">
                        <complexType>
                            <sequence>
                                <!--定义name和age简单元素-->
                                <element name = "name" type = "string"></element>
                                <element name = "age" type = "string"></element>
                            </sequence>
                        <!--定义属性,required( 必须的)/optional( 可选的)-->
                            <attribute name="id" type="string" use="required"></attribute>
                        </complexType>
                    </element>
                </sequence>
            </complexType>
        </element>
    </schema>

2、引入schema约束

  1. 在根标签上定义属性xmlns="http://www.w3.org/2001/XMLSchema-instance"

  2. 通过xmlns引入约束文件的名称空间

  3. 给某一个xmlns属性添加一个标识,用于区分不同的名称空间
    xmlns:标识=“名称空间地址” ,标识可以是任意的,但是一般取值都是xsi

  4. 通过xsi:schemaLocation指定名称空间所对应的约束文件路径
    xsi:schemaLocation = "名称空间url 文件路径“

    <?xml version="1.0" encoding="UTF-8" ?>

    <persons
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.itheima.cn/javase"
        xsi:schemaLocation="http://www.itheima.cn/javase person.xsd"
    >
        <person>
            <name>张三</name>
            <age>23</age>
        </person>

    </persons>

五、注解

1、 概述

  • 对我们的程序进行标注和解释
  • 使用注解进行配置配置的优势
  • 注解和注释的区别
    • 注释: 给程序员看的
    • 注解: 给编译器看的

2、自定义注解

  public @interface 注解名称 {
    public 属性类型 属性名() default 默认值 ;
  }
  • 属性类型

    • 基本数据类型
    • String
    • Class
    • 注解
    • 枚举
    • 以上类型的一维数组
  • 注意
    如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可

//表示Test这个注解的存活时间
    @Retention(value = RetentionPolicy.RUNTIME)
    public @interface Test {
    }

    public class UseTest {

        //没有使用Test注解
        public void show(){
            System.out.println("UseTest....show....");
        }

        //使用Test注解
        @Test
        public void method(){
            System.out.println("UseTest....method....");
        }

        //没有使用Test注解
        @Test
        public void function(){
            System.out.println("UseTest....function....");
        }
    }

    public class AnnoDemo {
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException {
            //1.通过反射获取UseTest类的字节码文件对象
            Class clazz = Class.forName("com.itheima.myanno3.UseTest");

            //创建对象
            UseTest useTest = (UseTest) clazz.newInstance();

            //2.通过反射获取这个类里面所有的方法对象
            Method[] methods = clazz.getDeclaredMethods();

            //3.遍历数组,得到每一个方法对象
            for (Method method : methods) {
                //method依次表示每一个方法对象。
                //isAnnotationPresent(Class<? extends Annotation> annotationClass)
                //判断当前方法上是否有指定的注解。
                //参数:注解的字节码文件对象
                //返回值:布尔结果。  true 存在  false 不存在
                if(method.isAnnotationPresent(Test.class)){
                    method.invoke(useTest);
                }
            }
        }
    }

3、元注解

  • 元注解就是描述注解的注解

    元注解名 说明
    @Target 指定了注解能在哪里使用
    @Retention 可以理解为保留时间(生命周期)
    @Inherited 表示修饰的自定义注解可以被子类继承
    @Documented 表示该自定义注解,会出现在API文档里面。
  @Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD})  //指定注解使用的位置(成员变量,类,方法)
  @Retention(RetentionPolicy.RUNTIME) //指定该注解的存活时间
  //@Inherited //指定该注解可以被继承
  public @interface Anno {
  }

  @Anno
  public class Person {
  }

  public class Student extends Person {
      public void show(){
          System.out.println("student.......show..........");
      }
  }

  public class StudentDemo {
      public static void main(String[] args) throws ClassNotFoundException {
          //获取到Student类的字节码文件对象
          Class clazz = Class.forName("com.itheima.myanno4.Student");

          //获取注解。
          boolean result = clazz.isAnnotationPresent(Anno.class);
          System.out.println(result);
      }
  }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容