XML和Dom4j、正则表达式

day15 XML和Dom4j、正则表达式

今日内容:
	[重点]a.XML(作为框架的配置文件)
    [重点]b.Dom4J(第三方框架,用来解析XML文件) 
    [理解]c.正则表达式    

第一章 XML概述

1.XML的初体验
  • XML的介绍以及版本

    XML(EXtensible Markup Language): 可扩展的标记语言
        语言:XML也是一种语言
        标记:标签 <开始标签>  </结束标签> 
        可扩展: 标签可以随意扩展 
    XML的版本
        XML 1.0 (99.9999%都使用该版本)
        XML 1.1 (基本没人使用)      
    
  • XML 与 HTML 的主要差异

    a.XML是可扩展的标记 HTML是预先定义好的标记
    b.XML主旨是传输和存储数据 HTML主旨是显示数据    
    
  • XML小案例

    • 需求:

      使用XML,保存一个Person的信息(id,姓名,年龄)
      
    • 编写

      在Java代码:
      	public class Person{
              String id;
              String name;
              int age;
              String sex;
              //其他省略
          }
      	一个Person就是一个对象:
      	Person p1 = new Person("007","张三",20,"男");
      	Person p2 = new Person("008","李四",30,"女");
      	把多个对象添加到一个集合中:
      	ArrayList<Person> persons = new ArrayList<Person>();
      	persons.add(p1);
      	persons.add(p2);
      在XML中:
      	<persons>
              <person id="007">
                  <name>张三</name>
                  <age>20</age>
                  <sex></sex>
              </person>
      
              <person id="008">
                  <name>李四</name>
                  <age>30</age>
                  <sex></sex>
              </person>
          </persons>    
      
    • 运行

      使用浏览器打开即可(火狐和谷歌)
      
  • XML的作用

    a.传输数据(基本上被json代替)
    b.保存数据(a.真的用于保存数据就像案例中 b.作为框架的配置文件)
    
2.XML的语法学习
  • XML的组成元素**********************

    • 文档声明

      什么是文档声明: 表明该文件是一个XML的文档
      <?xml version="1.0" encoding="utf-8" ?>   
      a.文档声明必须出现在XML文档第0行第0(左上角) 
      b.文档声明中有两个属性:version,encoding
          其中version表示XML的版本,必须写,值是"1.0"
          其中encoding表示XML的编码,可以不写(不建议),值是"utf-8"    
      
    • 元素element/标签(Tag)/节点(Node)

      a.XML最主要的组成部分:
      	元素<Element>/标签<Tag>/节点(Node)
          格式: <开始标签>标签体</结束标签>    
      b.普通的标准由: <开始标签> + 标签体 + </结束标签> 三部分组成
      c.标签体: 可以是其他普通标签也可以普通文本内容
      d.空标签: <开始标签></结束标签> 建议写成自闭合标签:<标签/>  
      e.标签的名字: 
      	a.大小写区分
          b.不要使用特殊符号(空格,冒号,分号等)  
          c.不建议以xml相关的开头
      f.一个标准的XML文档,有且仅有一个根标签        
      
    • 属性attribute

      a.属性必须写在开始标签内
      b.属性的格式: 属性名="属性值",无论属性值是什么类型的,必须使用""或者''引起来
      c.一个标签中属性可以是0-N个,但是不允许有相同名字的属性
      d.属性名不可以有空格等特殊符号,必须以字母开头    
      
    • 注释

      <!--注释内容-->
      <!--
          注释内容
          注释内容
          注释内容
      -->    
      
    • 转义字符

      <	--> &lt;
      >   --> &gt;
      "	--> &quot;
      '   --> &apos;
      &	--> &amp; 
      
      <?xml version="1.0" encoding="UTF-8"?>
      <code>
          for(int i = 0;i &lt; 10;i++){
              System.out.println(&quot;&lt;code&gt;&quot;);
          }
      </code>
      
    • 字符区/CDATA区(了解)

      在字符区中所有的字符,我们正常写即可,XML会帮助我们自动转义
      字符区:
      	<![CDATA[
              字符区内容
          ]]>
              
      <?xml version="1.0" encoding="UTF-8"?>
      <code>
          <![CDATA[
              for(int i = 0;i < 10;i++){
                  System.out.println("");
              }
          ]]>
      </code>       
      

第二章 XML约束

1.DTD约束
  • 什么是DTD约束

    DTD约束: 文档类型定义约束
    作用: 用于约束我们写的XML文档    
    
  • DTD约束体验

    我们的重点不是学习DTD怎么写,而是只要根据DTD编写出符合要求XML即可!!!!!!
        
    a.复制bookshelf.dtd文件  
    b.创建我们的XML文档  
    c.在我们的XML文档,引入DTD约束
    d.根据IDEA的提示,完成XML即可    
        
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE 书架 SYSTEM "bookshelf.dtd">
    <书架>
        <>
            <书名>三国演义</书名>
            <作者>罗贯中</作者>
            <售价>100</售价>
        </>
    
        <>
            <书名>水浒传</书名>
            <作者>施耐庵</作者>
            <售价>200</售价>
        </>
    </书架>    
    
  • DTD约束语法(了解)

    • DTD的引入

      内部DTD:
      	直接将DTD写到某个XML内部 -- 只能给当前的XML使用(一般不用)
              
      外部DTD -- 本地DTD  -- 一般用于公司内部
           <!DOCTYPE 根元素 SYSTEM "bookshelf.dtd">   
      外部DTD -- 公共DTD   -- 所有公司均可使用,一般是各种框架提供
           <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">   
      
    • DTD中的数量词

      标签名* ---> 表示该标签可以出现0-N次
      标签名+ ---> 表示该标签可以出现1-N次    
      标签名? ---> 表示该标签可以出现0-1次
      标签1,标签2,标签3 --->  表示三个标签必须按照前后顺序出现
      标签1|标签2|标签3 --->  表示三个标签可以选中出现其中一个    
      
    • 其他语法了解即可

      有关属性和类型和可选说明我们了解即可
      
2.schema约束
  • 什么是Schema约束

    也是一种XML约束,比DTD更加强大(主要强大在数据类型的约束上)
    Schema约束文档,本质上也是一个XML文档,但是后缀是.xsd    
    
  • Schema约束体验

    a.复制schema约束文件bookshelf.xsd
    b.创建我们自己的XML文档
    c.在我们的XML文档中引入xsd约束
    d.根据IDEA的提示,编写符合要求的XML即可
        
    <?xml version="1.0" encoding="UTF-8"?>
    <书架 xmlns="http://www.itcast.cn"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.itcast.cn bookshelf.xsd">
        <>
            <书名>三国演义</书名>
            <作者>罗贯中</作者>
            <售价>100</售价>
        </>
        <>
            <书名>红楼梦</书名>
            <作者>曹雪芹</作者>
            <售价>200</售价>
        </>
    </书架>    
    
  • Schema的语法和命名空间(了解即可)

    Schema约束中的标签,属性,数据类型等我们了解即可
        
    在Schemal约束中有一种称为命名空间的东西:
    	命名空间 类似于Java中的包
        package 包名;
    	targetNamespace="http://www.itcast.cn"
        使用命名空间时:
    	xmlns="http://www.itcast.cn" (默认名空间)
        xmlns:别名="http://www.itcast.cn" (别名命名空间)       
    
3.XML约束的学习要求
我们学习XML约束,不是学习如何编写DTD和Schema,
而是根据DTD和Schema约束,配合IDEA提示完成符合要求的XML!!!!

第三章 XML解析

1. 什么是XML解析
通过Java代码,解析出XML中所保存的数据
2. 解析方式和解析器和解析开发包
XML的解析方式(理论,思想):
	DOM解析: 把整个XML读取到内存中,然后整体解析,解析后返回一个Document对象
        a)优点:元素与元素之间保留结构关系,故可以进行增删改查操作。
		b)缺点:XML文档过大,可能出现内存溢出
    SAX解析: 将XML文件读一行,解析一行,释放这一行
        a)优点:处理速度快,可以处理大文件
		b)缺点:只能读,逐行后将释放资源,解析操作繁琐。
	PULL解析: 是Android的解析方式        
XML的解析器(代码实现):
	对DOM解析理论和SAX解析理解进行具体的代码实现
    解析器不一定是Java代码,而且API非常繁琐(因为需要考虑每一个细节)       
XML的解析开发包(对代码进一步封装):
	对于解析器中繁琐的API进行封装,封装之后API大大简化了我们的开发
        
常见的解析开发包:
	Dom4j解析开发包(使用Dom解析方式)               
3. Dom4j的基本使用
  • DOM解析的原理

    将整个XML一次性读取到内存进行解析,解析后返回一个Document对象(XML文档对象)
    
  • DOM树的结构模型

    <?xml version="1.0" encoding="UTF-8"?> 
        <books> <book id="0001"> 
        	<name>JavaWeb开发教程</name> 
        	<author>张孝祥</author> 
        	<sale>100.00</sale> 
        </book> 
        <book id="0002"> 
        	<name>三国演义</name> 
        	<author>罗贯中</author> 
        	<sale>100.00</sale> 
        </book> 
    </books>
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F8HbzIV9-1578312782570)(img/image-20200106113529119.png)]

  • DOM4J的jar包和常用API

    DOM4JAPI:
    	核心类:SaxReader(用于加载XML文件)
        构造:
    		public SaxReader() 构造器
            public Document read(String url); 将文件读取到内存并解析,解析后返回Document对象
                
    Document类:
    	public Element getRootElement() 获得根元素
            
    Element类:
    	public List elements([String name]); 列出当前元素[指定名字]下所有的子元素
        public Element element([String name]); 获取当前元素下[指定名字]的第一子元素
        public String getName(); 获取当前元素的元素名(标签名)
        public String attributeValue(String attrName);获取当前元素的某个指定属性值 
        public String getText(); 获取当前元素的文本内容
        public String elementText(Sting ele);获取当前元素下指定第一个子元素的文本      
    
  • DOM4J代码演示

    books.xml
        	<books>
           		<book id="0001">
                    <name>JavaWeb开发教程</name>
                    <author>张孝祥</author>
                    <sale>100.00</sale>
                </book>
                <book id="0002">
                    <name>三国演义</name>
                    <author>罗贯中</author>
                    <sale>100.00</sale>
                </book>
            </books>
        注意:解析的时候目前不需要引入约束
        
    /**
     * 解析books.xml
     */
    public class Dom4JDemo {
        public static void main(String[] args) throws DocumentException {
            //1.Dom4J核心类,SAXReader
            SAXReader reader = new SAXReader();
            //2.读取整个XML,解析返回Document对象
            //从Dom4JDemo的文件的根文件找
    //        InputStream in = Dom4JDemo.class.getResourceAsStream("/books.xml");
    //从src下找
            InputStream in = Dom4JDemo.class.getClassLoader().getResourceAsStream("books.xml");
            Document document = reader.read(in);
    //        3.获取根元素
            Element rootElement = document.getRootElement();
            System.out.println(rootElement.getName());
    //        4.获取所有的子元素
            List<Element> elements = rootElement.elements();
    //        5.遍历集合
            for (Element bookElement : elements) {
                //6.获取book元素的属性
                String idValue = bookElement.attributeValue("id");
                System.out.println(bookElement.getName());
                System.out.println("id属性的值是:"+idValue);
                //7.获取book元素的子元素
                List<Element> eles = bookElement.elements();
                //8.遍历
                for (Element ele : eles) {
                    //9.获取元素名字
                    System.out.println(ele.getName());
                    //10.获取元素的文本
                    String text = ele.getText();
                    System.out.println("文本内容是:"+text);
                }
            }
        }
    }       
    
4. Dom4J结合XPath解析XML
  • 什么是XPath

    通过"XPath路径表达式"来快速获取整个XML文档中我们需要的元素或者属性
    
  • XPath使用步骤

    public List selectNodes("路径表达式"); 快速获取多个符合要求的节点
    public Element selectSingleNode("表达式");  快速获取符合要求的单个节点  
    
  • XPath语法(了解)

     绝对路径表达式方式 例如: /元素/子元素/子子元素...
     相对路径表达式方式 例如: 子元素/子子元素.. 或者 ./子元素/子子元素.. 
     全文搜索路径表达式方式 例如: //子元素//子子元素     
     条件筛选/谓语表达式方式 例如://元素[@attr1=value]	
    
    public class XPathDemo {
        public static void main(String[] args) throws DocumentException {
            //1.Dom4J核心类,SAXReader
            SAXReader reader = new SAXReader();
            //2.读取整个XML,解析返回Document对象
    //        InputStream in = Dom4JDemo.class.getResourceAsStream("/books.xml");
            InputStream in = Dom4JDemo.class.getClassLoader().getResourceAsStream("books.xml");
            Document document = reader.read(in);
    
            //3.使用Xpath
            //a.绝对路径
            List<Node> nodes = document.selectNodes("/books/book/sale");
            for (Node node : nodes) {
                String text = node.getText();
                System.out.println(text);
            }
    
            //c.全文搜索路径
            List<Node> nodes1 = document.selectNodes("//name");
            for (Node node : nodes1) {
                System.out.println(node.getText());
            }
            //d.条件筛选
            Node node = document.selectSingleNode("//book[@id=0001]");
            System.out.println(node.getName());
    
            //b.相对路径
            Node node1 = node.selectSingleNode("name");
            System.out.println(node1.getText());
        }
    }
    

第四章 正则表达式

1. 正则表达式的概念及演示
什么是正则表达式:
	本质上就一个字符串,和普通字符串的区别在于其内容
        普通的字符串的内容就是内容,正则表达式的内容而是代表某个规则
    比如:
		String str = "HelloWorld"; 普通字符串
        String regex = "\\d{4,9}"; 正则表达式 
            
     作用: 可以通过正则表达式来判断某个字符串是否符合该规则
     在String类中有一个方法:
			public boolean matches(String regex); 判断当前字符串是否正则的规则,符合则true
案例:
	需求:下面的程序让用户输入一个QQ号码,我们要验证:
        QQ号码必须是5--15位长度
        而且必须全部是数字
        而且首位不能为0
public class RegexDemo {
    public static void main(String[] args) {
//        案例:
//        需求:下面的程序让用户输入一个QQ号码,我们要验证:
//        QQ号码必须是5--15位长度
//        而且必须全部是数字
//        而且首位不能为0
        System.out.println("请输入您的QQ号码:");
        String qq = new Scanner(System.in).nextLine();
        //判断
        if (qq.length() < 5 || qq.length() > 15) {
            System.out.println("长度不满足...");
            return;
        }

        for (int i = 0; i < qq.length(); i++) {
            char ch = qq.charAt(i);
            if (ch < '0' || ch > '9') {
                System.out.println("不全是数字..");
                return;
            }
        }

        if (qq.charAt(0) == '0') {
            System.out.println("首位不能为0");
            return;
        }
        System.out.println("您的QQ是合法的!!");
        
        
        //正则表达式,他是一位一位判断的 1345563
        boolean b = qq.matches("[1-9][0-9]{4,14}");
        if (b) {
            System.out.println("您的QQ是合法的!!");
        }else{
            System.out.println("您的QQ不合法的!!");
        }
    }
}                
2. 正则表达式-字符类
public class RegexDemo01 {
    public static void main(String[] args) {
        String str = "ead";
        //1.验证str是否以h开头,以d结尾,中间是a,e,i,o,u中某个字符
        System.out.println(str.matches("h[aeiou]d"));

        //2.验证str是否以h开头,以d结尾,中间不是a,e,i,o,u中的某个字符
        System.out.println(str.matches("h[^aeiou]d"));

        //3.验证str是否a-z的任何一个小写字符开头,后跟ad
        System.out.println(str.matches("[a-z]ad"));

        //4.验证str是否以a-d或者m-p之间某个字符开头,后跟ad
        System.out.println(str.matches("[a-dm-p]ad"));

    }
}
3. 正则表达式-逻辑运算符
public class RegexDemo02 {
    public static void main(String[] args) {
        String str = "bad";
        //1.要求字符串是小写(a,e,i,o,u元音字符)字符开头,后跟ad
        System.out.println(str.matches("[^aeiou&&a-z]ad"));

        //2.要求字符串是aeiou中的某个字符开头,后跟ad
        System.out.println(str.matches("[a|e|i|o|u]ad"));
    }
}
4. 正则表达式-预定义字符
public class RegexDemo03 {
    public static void main(String[] args) {
        String str = "2a8";
        //1.验证str是否3位数字
        System.out.println(str.matches("\\d\\d\\d"));
        //2.验证手机号:1开头,第二位:3/5/8,剩下9位都是0-9的数字
        str = "13513153355";
        System.out.println(str.matches("1[358]\\d{9}"));
        //3.验证字符串是否以h开头,以d结尾,中间是任何字符
        str = "h d";
        System.out.println(str.matches("h.d"));

        //4.验证str是否是:had.
        str = "had.";
        System.out.println(str.matches("had\\."));
    }
}
5. 正则表达式-数量词
public class RegexDemo04 {
    public static void main(String[] args) {
        String str = "";
        //1.验证str是否是三位数字
        str = "012";
        System.out.println(str.matches("\\d{3}"));
        //2.验证str是否是多位数
        str = "82345678987432345689943234578";
        System.out.println(str.matches("\\d{2,}"));
        //3.验证str是否是手机号:
        str = "13813183388";
        System.out.println(str.matches("1\\d{10}"));
        //4.验证小数:必须出现小数点,但是只能出现1次
        str = "3.0";
        System.out.println(str.matches("[0-9]+\\.[0-9]+"));

        //5.验证小数:小数点可以不出现,也可以出现1次
        str = "3.0";
        System.out.println(str.matches("[0-9]+\\.?[0-9]+"));
        //6.验证小数:要求匹配:3、3.、3.14、+3.14、-3.
        str = "3.14";
        System.out.println(str.matches("[+-]?3\\.?1?4?"));

        //7.验证qq号码:1).5--15位;2).全部是数字;3).第一位不是0
        str = "38385438";
        System.out.println(str.matches("[1-9]\\d{4,14}"));
    }
}
6. 正则表达式-分组括号( )
public class RegexDemo05 {
    public static void main(String[] args) {
        String str = "DG8FV-B9TKY-FRT9J-99899-XPQ4G";
        //验证这个序列号:分为5组,每组之间使用-隔开,每组由5位A-Z或者0-9的字符组成
        System.out.println(str.matches("([A-Z0-9]{5}-){4}[A-Z0-9]{5}"));
    }
}
7. String的split方法
public String[] split(String regex); 以指定的分割符来分割字符串,分割符支持正则表达式
    
public class RegexDemo06 {
    public static void main(String[] args) {
        String str = "18    4   567  99           56";
        //1.使用空格
        String[] strs = str.split(" ");
        for (String s : strs) {
            System.out.println(s);
        }
        //2.使用正则
        String[] strs1 = str.split(" +");
        for (String s : strs1) {
            System.out.println(s);
        }
        System.out.println("-----------");
        String s2 = "3566.+.3577.+.45667..++..34667";
        String[] ss = s2.split("\\.+\\++\\.+");
        for (String s : ss) {
            System.out.println(s);
        }
    }
}    
8. String类的replaceAll方法
public String replaceAll(String regex, String replacement);将当前字符串中的所有的子串替换为其他字符串 
 
public class RegexDemo07 {
    public static void main(String[] args) {
        String content = "TMD我去TMD你大爷,TMD,滚!!TMD";
        //敏感词过滤(替换)
        String s1 = content.replaceAll("TMD", "***");
        System.out.println(s1);

        //将下面字符串中的"数字"替换为"*"
        String str = "jfdk432jfdk2jk24354j47jk5l31324";
        String s2 = str.replaceAll("\\d", "*");
        System.out.println(s2);
    }
}    

你可能感兴趣的:(XML和Dom4j、正则表达式)