一、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文件中可以存在以下特殊字符
< < 小于 > > 大于 & & 和号 ' ' 单引号 " " 引号
二、约束
什么是约束
用来限定xml文件中可使用的标签以及属性-
约束的分类
- DTD
- schema
-
schema和dtd的区别
- schema约束文件也是一个xml文件,符合xml的语法,这个文件的后缀名.xsd
- 一个xml中可以引用多个schema约束文件,多个schema使用名称空间区分(名称空间类似于java包名)
- dtd里面元素类型的取值比较单一常见的是PCDATA类型,但是在schema里面可以支持很多个数据类型
- schema 语法更加的复杂
三、DTD
1、 编写DTD约束
-
步骤
- 创建一个文件,这个文件的后缀名为.dtd
- 看xml文件中使用了哪些元素
<!ELEMENT> 可以定义元素 - 判断元素是简单元素还是复杂元素
简单元素:没有子元素。
复杂元素:有子元素的元素;
<!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 元素名 元素类型>
- 简单元素:
- EMPTY: 表示标签体为空
- ANY: 表示标签体可以为空也可以不为空
- PCDATA: 表示该元素的内容部分为字符串
- 复杂元素:
- 直接写子元素名称. 多个子元素可以使用","或者"|"隔开;
- ","表示定义子元素的顺序 ; "|": 表示子元素只能出现任意一个
- "?"零次或一次, "+"一次或多次, "*"零次或多次;如果不写则表示出现一次
定义属性
定义一个属性的格式为:<!ATTLIST 元素名称 属性名称 属性的类型 属性的约束>
- 属性的类型:
CDATA类型:普通的字符串 - 属性的约束:
-
REQUIRED: 必须的
-
IMPLIED: 属性不是必需的
-
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约束
<?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约束
在根标签上定义属性xmlns="http://www.w3.org/2001/XMLSchema-instance"
通过xmlns引入约束文件的名称空间
给某一个xmlns属性添加一个标识,用于区分不同的名称空间
xmlns:标识=“名称空间地址” ,标识可以是任意的,但是一般取值都是xsi
通过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);
}
}