xml、DTD、schema、枚举

目录

xml-概述

xml-标签的规则

xml-语法规则

xml-DOM解析思想

xml-解析的准备工作

xml-解析代码实现

DTD-入门案例-编写DTD

DTD-入门案例-引入DTD

DTD-约束-三种引入方式

DTD-语法规则-定义元素

schema-schema和dtd的区别

schema入门案例-编写schema

schema入门案例-引入schema

schema入门案例-定义属性

枚举-什么是枚举

枚举-定义格式

枚举的特点

枚举的方法


xml-概述

万维网联盟(W3C)
            万维网联盟(W3C)创建于1994年, 又称W3C理事会, 是Web技术领域最具权威和影响力的标准机构
            1994年10月在麻省理工学院计算机科学实验室成立, 建立者蒂姆·伯纳斯·李
            到目前为止, W3C已经发布了200多项影响深远的Web技术标准及实施指南
                        1. 广为业界采用的超文本标记语言HTML
                        2. 可扩展标记语言xml
                        3. 帮助残障人士有效获得Web信息的无障碍指南WCAG等
        
什么是xml?
            全称为EXtensible Markup Language, 是一种可扩展的标记语言
            标记语言: 通过标签来描述数据的一门语言(标签有时也称之为元素)
            可扩展: 标签的名字是可以自定义的
            简单理解: xml文件是由很多标签组成的, 而标签的名字是可以自定义的
    
xml的作用?
    1. 存储数据和传输数据 
    2. 作为软件的配置文件

xml-标签的规则

    1. 标签由一对尖括号和合法的标识符组成
        <student>
        
    2. 标签必须成对出现
        <student></student>
        
    3. 特殊的标签可以不成对, 但是必须写结束标签
        </address>
        
    4. 标签中可以定义属性, 属性和标签名用空格隔开, 属性值必须用引号引起来
        <student id="1"></student>
        
    5. 标签需要正确的嵌套
        <student id="1">
            <name>张三</name>
        </student>

xml-语法规则

    1. xml文件的后缀必须是xml
    
    2. 文档声明必须是第一行第一列, 注释也不能写第一行
        <?xml version="1.0" encoding="UTF-8" standalone="yes/no" ?>
            version: 必须存在
            encoding: 不是必须存在, 表示当前xml字符集, 一般都是UTF-8
            standalone: 不是必须存在, 表示当前xml文件是否依赖其他xml, 取值为yes或者no
            
    3.必须存在一个根标签, 有且只能有一个
    
    4. xml文件中可以定义注释信息, 格式为<!--注释内容-->
                
        注释的快捷键: Ctrl+/  
            
    5. xml文件中可以定义一下特殊字符
        &lt;     <     小于
        &gt;     >     大于
        &amp;     &     和号
        &apos;     '     单引号
        &quot;     "     双引号
            
    6. xml文件中可以存在CDATA区
        <![CDATA[...内容...]]>

<?xml version="1.0" encoding="UTF-8" ?>
    <!--文档声明必须在文件的第一行第一列, 注释也不能写第一行-->
    <!--注释的快捷键: Ctrl+/-->
    <students>
        <student id="1">
            <name>zhangsan</name>
            <age>18</age>
            <info>&lt;&lt;&lt;&gt;&gt;&gt;</info>
            <!--CDATA区中可以写简单的文本, 不用复杂的符号代替-->
            <message><![CDATA[内容<<< >>>]]></message>
        </student>

        <student id="2">
            <name>lisi</name>
            <age>24</age>
        </student>
    </students>

xml-DOM解析思想

 DOM解析思想?
    DOM(document Object Model) 文档对象模型
    将文档的各个组成部分看做是对应的对象
    首先会将xml文件全部加载到内存, 在内存中形成一个树状结构, 在获取对应的值
    
对象分类
    1. Document对象: 整个xml文档
    2. Element对象: 所有标签   
    3. Attribute对象: 所有属性 
    4. Text对象: 所有文本内容  

    
重点记忆! 
    DOM解析思想就是一层一层的进入, 一层一层的解析

xml-解析的准备工作

常见的解析工具
    JAXP: SUN公司提供的一套xml解析的API
    JDOM: 开源组织提供的一套xml解析的API-jdom
    * DOM4J: 开源组织提供的一套xml解析的API-dom4j (全称Dom for Java)
    pill: 主要用在Android手机端解析xml
    
DOM4J解析xml文件准备
    1. 将dom4j-1.6.1.jar拖入IDEA的libs(新建)文件夹下
    2. 对着jar包右键, As library..
    3. 查看API入门案例

public class Foo {
            public Document parse(URL url) throws DocumentException {
                SAXReader reader = new SAXReader();
                Document document = reader.read(url);
                return document;
            }
        } 

xml-解析代码实现

案例需求:
	1. 解析这个xml文件
	2. 将解析的数据封装到学生对象中
	3. 将学生对象存储到ArrayList集合中
	4. 遍历集合
	
代码示例
    public class Test {
        public static void main(String[] args) throws DocumentException {
            //创建集合
            ArrayList<Student> list = new ArrayList<>();
            //获取解析器对象
            SAXReader reader = new SAXReader();
            //将xml加载进内存,获取文档对象
            Document document = reader.read("day17\\xml\\student.xml");
            //通过文档对象获取根标签students
            Element rootElement = document.getRootElement();
            //elements(); 获取所有子标签,返回集合
            //List list = rootElement.elements();
            //System.out.println(list.size()); //2个子标签

            //elements("标签名"); 获取所有指定的子标签,返回集合
            List<Element> studentElements = rootElement.elements("student");
            //遍历集合, element依次表示每一个student标签
            for (Element element : studentElements) {
                //获取id属性对象(attribute对象), 然后获取id属性值
                Attribute attribute = element.attribute("id");
                String id = attribute.getValue();
                //获取name标签对象(Element对象), 然后获取标签体
                Element nameElement = element.element("name");
                String name = nameElement.getText();
                //获取age标签对象(Element对象), 然后获取标签体
                Element ageElement = element.element("age");
                String age = ageElement.getText();
                //测试
                //System.out.println(id+","+name+","+age);
                //封装对象并添加到list集合
                list.add(new Student(id, name, Integer.parseInt(age)));
            }

            //遍历集合复习
            System.out.println("---------------迭代器");
            Iterator<Student> it = list.iterator();
            while (it.hasNext()) {
                System.out.println(it.next());
            }
            System.out.println("---------------增强for");
            for (Student student : list) {
                System.out.println(student);
            }
            System.out.println("---------------普通for");
            for (int i = 0; i < list.size(); i++) {
                System.out.println(list.get(i));
            }
            System.out.println("---------------直接打印");
            System.out.println(list);
        }
    }

。。。标准Student类。。。

DTD-入门案例-编写DTD

什么是xml约束?
    用来限定xml文件中可以使用的标签以及属性 -> 告诉程序员xml该怎么写
    
约束分类?
    1. DTD
    2. schema

    
DTD约束的编写步骤?
    步骤1. 创建一个文件, 后缀为.dtd 
    步骤2. 看xml文件中使用了哪些元素, <!ELEMENT>可以定义元素
    步骤3. 判断简单元素和复杂元素
(后面详细讲解)
        * 简单元素: 没有子元素 <!ELEMENT 元素名称 (#PCDATA)> #PCDATA表示是字符串类型
        * 复杂元素: 有子元素 <!ELEMENT 元素名称 (子元素名称1,子元素名称2...)>


代码示例
    <!ELEMENT persons (person)>
    <!ELEMENT person (name,age)>
    <!ELEMENT name (#PCDATA)>
    <!ELEMENT age (#PCDATA)>

DTD-入门案例-引入DTD

 DTD的学习目标
    目标1. 能在xml中引入约束文档
    目标2. 能够简单的阅读约束文档
    目标3. 根据约束能正确编写xml文件

引入DTD(方式1, 引入本地DTD)
    步骤1. 提供person.xml, 书写代码, 引入DTD约束
    步骤2. 书写错误标签检测

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

    <persons>
        <!--可以引用出所有属性-->
         <person>
             <name>张三</name>
             <age>23</age>
         </person>

        <!--如果书写范围外的标签,会报错<a></a>-->
    </persons>

DTD-约束-三种引入方式

    方式1. 引入本地DTD: 上个案例所示,
        <!DOCTYPE persons SYSTEM 'persondtd.dtd'>

        persons代表根标签名称
        SYSTEM代表是本地约束文档
        ''中代表约束文档名称
        
    方式2. 在xml文件内部引入: 在根标签后面, 使用[]直接书写约束内容

        <!DOCTYPE persons[
                    <!ELEMENT persons (person)>
                    <!ELEMENT person (name,age)>
                    <!ELEMENT name (#PCDATA)>
                    <!ELEMENT age (#PCDATA)>
        ]>

    方式3. 引入网络DTD: <!DOCTYPE persons "约束文档名称" "DTD约束文档的URL">

DTD-语法规则-定义元素

 定义属性语法规则?
    定义属性的格式: <!ATTLIST 元素名称 属性名称 属性类型 属性约束>
        属性类型:
            CDATA类型: 普通字符串
        属性约束:
            #REQUIRED 代表必须的
            #IMPLIED 代表不是必须的
            #FIXED "1p" value 代表属性值固定的

            

    <!ATTLIST person id CDATA #FIXED "p1"> //表示必须写成p1
    <!ATTLIST person id CDATA #REQUIRED> //表示id必须有值, 值随便写

schema-schema和dtd的区别

 schema和dtd的区别?
    1. schema约束文件也是一个xml文件, 符合xml语法, 这个文件的后缀名为.xsd
    2. 一个xml中可以引入多个schema约束文件, 多个schema使用"名称空间"区分 (类似java的包名)
    3. DTD中元素的类型比较单一, 常见的是PCDATA, 但是在schema中支持多种元素类型
    4. schema语法更加复杂
    
注意, 理解记忆!
    schema可以约束其他xml文件
    但是schema本身也是一个xml, 所以也被其他文件约束着

    

schema入门案例-编写schema

schema约束编写步骤?
    1. 创建文件后缀为.xsd
    2. 定义文档声明: <?xml version="1.0" encoding="UTF-8" ?> 
    3. schema文件的根标签为: <schema>, 属性有三个
    	xmlns="http://www.w3.org/2001/XMLSchema "
    	targetNamespace="唯一的自定义URL地址"
        固定格式表示文件质量良好: elementFormDefault="qualified      
    4. 通过element定义根标签: <element name="根标签名">
    5. 判断复杂元素和简单元素, 复杂元素需要写<complexType>和<sequence>
    	<!--复杂元素-->
    	<complexType> 
    		<!--子元素必须按照顺序定义-->
    		<sequence> 
    			<!--简单元素-->
    			<element name="属性名" type="string"></element>
				<element name="属性名" type="string"></element>
        	</sequence>
        </complexType>

根据xml文件写出schema约束
	<?xml version="1.0" encoding="UTF-8" ?>
    <cars>
        <car>
            <brand>宝马</brand>
            <price>200000</price>
        </car>
    </cars>
    
schema约束代码示例
    <?xml version="1.0" encoding="UTF-8" ?>
    <schema  xmlns="http://www.w3.org/2001/XMLSchema"
             targetNamespace="http://www.itheima.cn/javase"
             elementFormDefault="qualified"
    >
        <!--定义复杂元素cars-->
        <element name="cars">
            <complexType>
                <sequence>
                    <!--定义复杂元素car-->
                    <element name="car">
                        <complexType>
                            <sequence>
                                <!--定义简单元素name和age-->
                                <element name="brand" type="string"/>
                                <element name="price" type="string"/>
                            </sequence>
                        </complexType>
                    </element>
                </sequence>
            </complexType>
        </element>
    </schema>
    

schema入门案例-引入schema

引入schema步骤?
    1. 在根标签定义属性
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" //instance表示约束别人
    	xmlns="引入约束文件的名称空间"
    2. 由于有两个xmlns, 给某一个xmlns属性添加标识:xsi
    3. 通过xsi:schemaLocation="名称空间 文件路径"
        
引入schema代码示例
    <?xml version="1.0" encoding="UTF-8" ?>
    <cars
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns="http://www.itheima.cn/javase"
            xsi:schemaLocation="http://www.itheima.cn/javase carschema.xsd"
    >
        <car>
            <brand>宝马</brand>
            <price>200000</price>
        </car>
    </cars>
	

schema入门案例-定义属性

schema定义属性?
    在约束文件中</sequence>后</complexType>前书写
    	<attribute name="id" type="string" use="required"></attribute>
    		use="required" 必须的
   			use="optional" 可选的
    
代码示例
	//carschema.xsd定义属性id
    <?xml version="1.0" encoding="UTF-8" ?>
    <schema  xmlns="http://www.w3.org/2001/XMLSchema"
             targetNamespace="http://www.itheima.cn/javase"
             elementFormDefault="qualified"
    >
        <!--定义复杂元素cars-->
        <element name="cars">
            <complexType>
                <sequence>
                    <!--定义复杂元素car-->
                    <element name="car">
                        <complexType>
                            <sequence>
                                <!--定义简单元素name和age-->
                                <element name="brand" type="string"/>
                                <element name="price" type="string"/>
                            </sequence>
                            <!--定义属性-->
                            <attribute name="id" type="string" use="required"></attribute>
                        </complexType>
                    </element>
                </sequence>
            </complexType>
        </element>
    </schema>

	//car.xml使用id属性
    <?xml version="1.0" encoding="UTF-8" ?>
    <cars
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns="http://www.itheima.cn/javase"
            xsi:schemaLocation="http://www.itheima.cn/javase carschema.xsd"
    >
        <car id="001">
            <brand>宝马</brand>
            <price>200000</price>
        </car>
    </cars>

枚举-什么是枚举

 思考如果我们要表示固定的几个值, 比如季节: spring, summer, autumn, winter
    public static final int SEASON_SPRING = 1;
    public static final int SEASON_SUMMER = 2;
    public static final int SEASON_AUTUMN = 3;
    public static final int SEASON_WINTER = 4;
    
上述代码的弊端?
    1. 代码不够简洁
    2. 不同类型的数据, 是通过名字区分的
    3. 不安全, 由于是数字类型, 就有可能使用这几个值做算数操作
    
什么是枚举?
    为了简洁的表示一些"固定的值", Java给我们提供了"枚举类型"
    枚举是指将变量的值一一列出来, 变量的值仅限于列举出来的值的范围内

枚举-定义格式

枚举的定义格式?
    public enum s{
        枚举项1,枚举项2,枚举项3,;
    }
    定义枚举要使用关键字enum

    
案例代码示例: 使用枚举表示春夏秋冬四个季节
    public enum Season {
       //枚举项
       SPRING,SUMMER,AUTUMN,WINTER
    }

枚举的特点

枚举的特点?
    1. 所有枚举类都是Enum的子类
    2. 我们可以通过"枚举类名.枚举项名称"去访问指定的枚举项
    3. 每一个枚举项, 其实就是该枚举类的一个对象 -> 重点记忆, 其他了解即可!
    4. 枚举也是一个类, 也"可以声明成员变量"
    5. 枚举类的"第一行上必须是枚举项", 如果没有后续代码, 最后一个枚举项后的分号可以省略, 不建议
    6. 枚举类"可以有构造器, 但是必须是私有的", 默认是private的, 使用枚举项: 枚举(""){};
    7. 枚举类也"可以有抽象方法, 但是枚举项必须重写该方法"

        
代码示例

   public enum Season {
       //枚举类的"第一行上必须是枚举项", 如果没有后续代码, 最后一个枚举项后的分号可以省略, 不建议
       //SPRING,SUMMER,AUTUMN,WINTER;

       //使用枚举项: 枚举(""){};
       SPRING("春"){
          @Override
          public void show() {
             System.out.println(this.name);
          }
       },SUMMER("夏"){
          @Override
          public void show() {
             System.out.println(this.name);
          }
       },AUTUMN("秋"){
          @Override
          public void show() {
             System.out.println(this.name);
          }
       },WINTER("冬"){
          @Override
          public void show() {
             System.out.println(this.name);
          }
       };

       //枚举也是一个类, 也"可以声明成员变量"
       //private String name;
       public String name;

       //枚举类"可以有构造器, 但是必须是私有的", 默认是private的
       //空参构造: 如果提供带参注释空参, 枚举项(对象)会报错
       //private Season() {}
       private Season() {}

       //带参构造
       private Season(String name) {
          this.name = name;
       }

       //抽象方法: 枚举类也"可以有抽象方法, 但是枚举项必须重写该方法"
       public abstract void show();
    }

    /*
       枚举的特点?
           1. 所有枚举类都是Enum的子类
           2. 我们可以通过"枚举类名.枚举项名称"去访问指定的枚举项
           3. 每一个枚举项, 其实就是该枚举类的一个对象 -> 重点记忆, 其他了解即可!
           4. 枚举也是一个类, 也"可以声明成员变量"
           5. 枚举类的"第一行上必须是枚举项", 如果没有后续代码, 最后一个枚举项后的分号可以省略, 不建议
           6. 枚举类"可以有构造器, 但是必须是私有的", 默认是private的, 使用枚举项: 枚举(""){};
           7. 枚举类也"可以有抽象方法, 但是枚举项必须重写该方法"
     */
    class SeasonTest{
       public static void main(String[] args) {
           //我们可以通过"枚举类名.枚举项名称"去访问指定的枚举项
          System.out.println(Season.SPRING); //SPRING
          System.out.println(Season.SUMMER); //SUMMER
          System.out.println(Season.AUTUMN); //AUTUMN
          System.out.println(Season.WINTER); //WINTER

          //每一个枚举项, 其实就是该枚举类的一个对象 -> 重点记忆, 其他了解即可!
          Season spring = Season.SPRING; //自动生成左边
       }
    }

枚举的方法

枚举的常用方法?
    1. String name();         获取枚举名称
    2. int ordinal();         返回枚举在枚举类中的索引值
    3. int compareTo(E o);         比较两个枚举项, 返回索引差值
    4. String toString();         返回枚举常量名称
    5. static <T> T valueOf(Class<T> type, String name);获取指定枚举类中指定名称的枚举值
    6. values();         获得所有枚举项

public class Test {
    public static void main(String[] args) {
        //1. String name(); 获取枚举名称
        String name = Week.MONDAY.name();
        System.out.println(name); //MONDAY

        System.out.println("------------------------");

        //2. int ordinal(); 返回枚举在枚举类中的索引值
        System.out.println(Week.MONDAY.ordinal()); //0
        System.out.println(Week.TUESDAY.ordinal()); //1
        System.out.println(Week.WEDNESDAY.ordinal()); //2
        System.out.println(Week.THURSDAY.ordinal()); //3
        System.out.println(Week.FRIDAY.ordinal()); //4
        System.out.println(Week.SATURDAY.ordinal()); //5
        System.out.println(Week.SUNDAY.ordinal()); //6

        System.out.println("------------------------");
        
        //3. int compareTo(E o); 比较两个枚举项, 返回索引差值
        System.out.println(Week.MONDAY.compareTo(Week.SUNDAY)); //0 - 6 = -6

        System.out.println("------------------------");

        //4. String toString(); 返回枚举常量名称
        String mondayValue = Week.MONDAY.toString();
        System.out.println(mondayValue); //MONDAY 一般不会直接用,

        System.out.println("------------------------");

        //5. static <T> T valueOf(Class<T> type, String name);获取指定枚举类中指定名称的枚举值
        Week monday = Enum.valueOf(Week.class, "MONDAY");
        System.out.println(monday); //MONDAY
        System.out.println(Week.MONDAY == monday); //true

        System.out.println("------------------------");

        //6. values(); 获得所有枚举项
        Week[] week = Week.values();
        for (Week value : week) {
            // 打印枚举项
            System.out.println(value);
            /*
                MONDAY
                MONDAY
                TUESDAY
                WEDNESDAY
                THURSDAY
                FRIDAY
                SATURDAY
                SUNDAY
             */
        }
    }
}

//枚举星期
enum Week{
    MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值