1.24Java-JDK新特性、表达式、XML解析

目录

1.24.1接口的新特性

1.24.1.1新增特性

1.24.1.2接口默认方法

1.24.1.3接口静态方法

1.24.1.4接口私有方法

 1.24.2表达式

1.24.2.1正则表达式

1.24.2.1.1作用

1.24.2.1.2规则

1.24.2.1.3示例

1.24.2.2Lambda表达式

1.24.2.2.1Lambda标准格式

1.24.2.2.2Lamdba省略规则

1.24.2.2.3示例

1.24.3XML

1.24.3.1什么是XML

1.24.3.1.1作用

1.24.3.1.2XML基础语法

1.24.3.2XML组成

文档声明

指令

标签

文本

1.24.3.3XML约束

1.24.3.3约束的分类

1.24.3.3.1DTD约束

1.24.3.3.2Schema约束

1.24.3.4XML解析

1.24.3.4.1sax解析

1.24.3.4.2dom解析

1.24.3.4.3jdom解析

1.24.3.4.4dom4j解析

1.24.3.4.5四种解析方式的对比

1.24.3.4.6常见的XML解析器


1.24.1接口的新特性

1.24.1.1新增特性

  • JDK1.7之前

    • 抽象方法
    • 常量
  • JDK1.8新增:

    • 默认方法 静态方法

  • JDK1.9新增:

    • 私有方法

1.24.1.2接口默认方法

使用 default 修饰,不可省略,供子类调用或者子类重写。

格式

public default 返回值类型  方法的名称(参数列表){
    方法体
}

优点:  如果今后项目代码已以经写好,后期可能要扩展,接口中加新的方法(功能),如果你加抽象方法(功能)所有的实现类有影响,所以针对以上后期可能要扩展功能的话,代码的维护性比较差,出现了默认方法。默认方法可以选择是否重写,也可以根据实际需求进行重写。

1.24.1.3接口静态方法

静态方法:使用 static 修饰,供接口直接调用。

静态与.class文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用

格式

public static 返回值类型 方法名称(参数列表){
    方法体
}

1.24.1.4接口私有方法

  • 普通私有方法

    只有默认方法可以调用。

  • 私有静态方法

    默认方法和静态方法可以调用。

私有方法

public interface MyInterfacePrivateA {
	//默认方法
    public default void methodDefault1() {
        System.out.println("默认方法1");
        methodCommon();
    }

    //默认方法
    public default void methodDefault2() {
        System.out.println("默认方法2");
        methodCommon();
    }

    //普通-私有方法
    private void methodCommon() {
        System.out.println("AAA");
        System.out.println("BBB");
        System.out.println("CCC");
    }

}

私有静态方法  

public interface MyInterfacePrivateB {
    //静态方法
    public static void methodStatic1() {
        System.out.println("静态方法1");
        methodStaticCommon();
    }

    //静态方法
    public static void methodStatic2() {
        System.out.println("静态方法2");
        methodStaticCommon();
    }

    //私有-静态方法
    private static void methodStaticCommon() {
        System.out.println("AAA");
        System.out.println("BBB");
        System.out.println("CCC");
    }
}

 1.24.2表达式

1.24.2.1正则表达式

1.24.2.1.1作用

正则表达式的作用

  • 校验字符是否满足规则

  • 在一段文本中查找满足要求的内容

1.24.2.1.2规则

字符类(只匹配一个字符)

[abc]

只能是a或b或c

[^abc]

除了a,b,c之外的任何字符

[a-zA-Z]

a到z,A到Z,包括(范围)

[a-d[m-p]]

(a到d),或者(m到p)

[a-z&&[def]]

(a到z)与(def)的交集

[a-z&&[^def]]

(a到z)与(除了def之外)的交集

[a-z&&[^m-p]]

(a到z)和(除了(m到p))的交集

预定义字符(只匹配一个字符)

.

任何字符

\d

一个数字:[0-9]

\D

非数字[^0-9]

\s

一空白字符[\t\n\x0B\f\r]

\S

非空白字符

\w

[a-zA-Z_0-9]英文、数字、下划线

\W

[^\w]一个非单词字符

数量词

X?

X,一次或0次

X*

X,0次或多次

X+

X,一次或多次

X{n}

X,正好n次

X{n,}

X,至少n次

X{n,m}

X,至少n次但不超过m次

1.24.2.1.3示例

字符类:

package com.yunhe.day0916;
//正则表达式
public class RegexDemo {
        public void main(String[] args){
                //public boolean matches(String regex); 判断是否符合正则表达式匹配,匹配返回true
                
                
                //只能是a b c
                System.out.println("------------1----------");
                System.out.println("a".matches("[abc]")); //true
                System.out.println("z".matches("[abc]"));//false
                        
                
                //不能是a b c
                System.out.println("------------2----------");
                System.out.println("a".matches("[^abc]")); //false
                System.out.println("z".matches("[^abc]"));//true
                System.out.println("zz".matches("[^abc]")); //false
                System.out.println("z".matches("[^abc][^abc]"));//true
                
                
                // a到z  A到Z
                System.out.println("------------3----------");
                System.out.println("a".matches("[a-zA-Z]")); //true
                System.out.println("z".matches("[a-zA-Z]"));//true
                System.out.println("aa".matches("[a-zA-Z]")); //false
                System.out.println("zz".matches("[a-zA-Z]"));//false
                System.out.println("0".matches("[a-zA-Z]"));//false
                
                
                // [a-d[m-p]]                 a到d,或m到p
                System.out.println("------------4----------");
                System.out.println("a".matches("[a-d[m-p]]")); //true
                System.out.println("d".matches("[a-d[m-p]]"));//true
                System.out.println("m".matches("[a-d[m-p]]")); //true
                System.out.println("p".matches("[a-d[m-p]]"));//true
                System.out.println("e".matches("[a-d[m-p]]"));//false
                System.out.println("0".matches("[a-d[m-p]]"));//false

                
                // [a-z&&[def]]                 a到d和def的交集,为d  e  f
                System.out.println("------------5----------");
                System.out.println("a".matches("[a-z&&[def]]")); //flase
                System.out.println("d".matches("[a-z&&[def]]"));//true
                System.out.println("e".matches("[a-z&&[def]]")); //false

                // [a-z&&[^bc]]                 a到z和非bc的交集
                System.out.println("------------6----------");
                System.out.println("a".matches("[a-z&&[^bc]]")); //true
                System.out.println("b".matches("[a-z&&[^bc]]"));//false
                System.out.println("0".matches("[a-z&&[^bc]]")); //false                
                
                
                // [a-z&&[^m-p]]                a到z和除了m到p的交集
                System.out.println("------------7----------");
                System.out.println("a".matches("[a-z&&[^m-p]]")); //true
                System.out.println("m".matches("[a-z&&[^m-p]]"));//false
                System.out.println("0".matches("[a-z&&[^m-p]]")); //false                
                
                
        }

}

 预定义字符:

package com.yunhe.day0916;
//正则表达式
public class RegexDemo {
        public void main(String[] args){
                //public boolean matches(String regex); 判断是否符合正则表达式匹配,匹配返回true
                
                
                //  .表示一个字符
                System.out.println("------------1----------");
                System.out.println("你".matches("..")); //false
                System.out.println("你".matches(".")); //true
                System.out.println("你a".matches(".."));//true
                        
                
                //不能是a b c
                System.out.println("------------2----------");
                System.out.println("a".matches("[^abc]")); //false
                System.out.println("z".matches("[^abc]"));//true
                System.out.println("zz".matches("[^abc]")); //false
                System.out.println("z".matches("[^abc][^abc]"));//true
                
                
                // \\d只能是任意的数字
                System.out.println("------------3----------");
                System.out.println("a".matches("\\d")); //false
                System.out.println("3".matches("\\d"));//true
                System.out.println("333".matches("\\d")); //false
        
                
                
                // \\w只能是一个单词字符  [a-zA-Z_0-9]
                System.out.println("------------4----------");
                System.out.println("z".matches("\\w")); //true
                System.out.println("2".matches("\\w"));//true
                System.out.println("21".matches("\\w")); //false
                System.out.println("你".matches("\\w"));//false
                
                //非单词字符
                System.out.println("你".matches("\\W"));//true

                
                // 必须是数字 字母  下划线  至少  6位
                System.out.println("------------5----------");
                System.out.println("2442fsfsf".matches("\\w{6,}")); //true
                System.out.println("244f".matches("\\w{6,}"));//false

                // 必须是数字和字符  必须是4位
                System.out.println("------------6----------");
                System.out.println("23dF".matches("[a-zA-Z0-9]{4}")); //true
                System.out.println("23_F".matches("[a-zA-Z0-9]{4}"));//false
                System.out.println("23dF".matches("[\\w&&[^_]]{4}")); //true                
                System.out.println("23_F".matches("[\\w&&[^_]]{4}")); //false                                
                
        }

}

1.24.2.2Lambda表达式

Lambda 表达式是 Java8 新增的重要特性,Lambda 使 Java 具有了类似函数式编程的风格

1.24.2.2.1Lambda标准格式

格式

  (形式参数) -> {

  代码块

  }

格式解析

  • 形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可

  • ->:由英文中画线和大于符号组成,固定写法。代表指向动作

  • 代码块:是我们具体要做的事情,也就是以前我们写的方法体内容

Lambad使用前提

  • Lambda表达式可以简化匿名内部类的书写

  • Lambda表达式只能简化函数式接口的匿名内部类的书写

  • 函数式接口:

    • 有且仅有一个抽象方法的接口叫函数式接口,接口上方可以加@FunctionInterface注解

1.24.2.2.2Lamdba省略规则

  • 参数类型可以省略不写

  • 如果只有一个参数,参数类型可以省略,同时()也可以省略

  • 如果Lamdba表达式的方法体只有一行,大括号,分号,return可以省略不写,需要同时省略

1.24.2.2.3示例

  Lamdba的书写步骤  
  
      
        String[] arr={"aaaa","aaa","a","aa"};             
        //法一:匿名内部类的方式
        Arrays.sort(arr,new Comparator<String>(){
                //字符串的长度进行排序
                public int compare(String o1, String o2) {
                        return o1.length()-o2.length();
                }
                
        });
        //打印数组
        System.out.println(Arrays.toString(arr));

                //But,我觉的太麻烦,换成Lamdba
       第一步:    atrl+点击  Comparator函数,进入它的定义中,查看它是不是函数式接口
                  ------------------------------------------------ 
                         @FunctionalInterface
                        public interface Comparator<T>
                  ------------------------------------------------ 
                发现有@FunctionalInterface,而且接口没有报错,就是函数式接口,所以
                它的匿名内部类对象,我们就可以用lamdba改进
       第二步:    从     new Comparator<String>(){
                         //字符串的长度进行排序
                         public int compare
                到方法名这里全部删除   
             得到1:
             ----------------------1--------------------------                  
                Arrays.sort(arr,(String o1, String o2) {
                                return o1.length()-o2.length();
                        }
                        
                });
                //打印数组
                System.out.println(Arrays.toString(arr));
            --------------------------------------------------   
            之后删除第33行的}
            得到2
             -----------------------2-------------------------                  
                Arrays.sort(arr,(String o1, String o2) {
                                return o1.length()-o2.length();
                        }
                        
                );
                //打印数组
                System.out.println(Arrays.toString(arr));
            -------------------------------------------------- 
            之后在40行加入->
            得到3,lamdba的完整格式
             -----------------------3-------------------------                  
                Arrays.sort(arr,(String o1, String o2) ->{
                                return o1.length()-o2.length();
                        }
                        
                );
                //打印数组
                System.out.println(Arrays.toString(arr));
            -------------------------------------------------- 
    第三步:  lamdba的简写格式
            //简写规则      
            //参数类型可以省略不写
        //如果只有一个参数,参数类型可以省略,同时()也可以省略
        //如果Lamdba表达式的方法体只有一行,大括号,分号,return可以省略不写,需要同时省略
        把参数省略
        得到4
            -----------------------4-------------------------                  
                Arrays.sort(arr,(o1,o2) ->{
                                return o1.length()-o2.length();
                        }
                        
                );
                //打印数组
                System.out.println(Arrays.toString(arr));
            -------------------------------------------------- 
            把大括号,分号,return省略
             得到5
            -----------------------5-------------------------                  
                Arrays.sort(arr,(o1,o2) ->
                                o1.length()-o2.length()                                               
                );
                //打印数组
                System.out.println(Arrays.toString(arr));
            -------------------------------------------------- 
            整理后
             得到6
            -----------------------6-------------------------                  
                Arrays.sort(arr,(o1,o2) ->o1.length()-o2.length());
                //打印数组
                System.out.println(Arrays.toString(arr));
            -------------------------------------------------- 
   
   
            对比
           ---------------------匿名内部类----------------------------- 
             Arrays.sort(arr,new Comparator<String>(){
                //字符串的长度进行排序
                public int compare(String o1, String o2) {
                        return o1.length()-o2.length();
                }              
                });
                //打印数组
                System.out.println(Arrays.toString(arr));      
            ---------------------------------------------------------


1.24.3XML

1.24.3.1什么是XML

Extensible Markup Language 可扩展标记语言

可扩展:标签都是自定义的。 

1.24.3.1.1作用

  1. 常用于存储数据和配置文件
  2. 最常用的功能就是xml做为一个配置文件
  3. 数据的传输   (已经被json替代)

1.24.3.1.2XML基础语法

  1. xml文档的后缀名.xml
  2. xml第一行必须定义为文档声明
  3. xml文档中有且仅有一个根标签
  4. 属性值必须使用引号(单双都可)引起来
  5. 标签必须正确关闭
  6. xml标签名称严格区分大小写

1.24.3.2XML组成

文档声明

<?xml 属性列表 ?>

属性列表

  • version:版本号,必须的属性【1.0】

  • encoding:编码方式。告知解析引擎当前文档使用的字符集,默认值:ISO-8859-1

  • standalone:是否独立

    • 取值:

      • yes:不依赖其他文件

      • no:依赖其他文件

指令

<?xml-stylesheet type="text/css" href="a.css" ?>

标签

  • 标签命名规则

    • 名称可以包含字母、数字以及其他的字符

    • 名称不能以数字或者标点符号开始

    • 名称不能以字母 xml(或者 XML、Xml 等等)开始

    • 名称不能包含空格

  • 最佳命名习惯

    • 名称简短,比如:<book_title>,而不是:<the_title_of_the_book>。

    • 避免 "-" 字符。如果您按照这样的方式进行命名:"first-name",一些软件会认为你需要提取第一个单词。

    • 避免 "." 字符。如果您按照这样的方式进行命名:"first.name",一些软件会认为 "name" 是对象 "first" 的属性。

    • 避免 ":" 字符。冒号会被转换为命名空间来使用(稍后介绍)。

    • XML 文档经常有一个对应的数据库,其中的字段会对应 XML 文档中的元素。有一个实用的经验,即使用数据库的名称规则来命名 XML 文档中的元素。

    • 非英语的字母比如 éòá 也是合法的 XML 元素名,不过需要留意当软件开发商不支持这些字符时可能出现的问题。

文本

CDATA区:在该区域中的数据会被原样展示

<![CDATA[ 数据 ]]>

1.24.3.3XML约束

约束:按照规则进行书写,称之为约束。

一个良好的 XML 文档要满足以下规则:

  1. XML 文档必须有根元素
  2. XML 文档必须有关闭标签
  3. XML 标签对大小写敏感
  4. XML 元素必须被正确的嵌套
  5. XML 属性必须加引号

1.24.3.3约束的分类

1.24.3.3.1DTD约束

DTD约束:document type definition 文档类型定义

约束编写

扩展名是:dtd

<!ELEMENT students (student*) >
<!ELEMENT student (name,age,sex)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!ATTLIST student number ID #REQUIRED>

DTD约束引入

内部dtd:将约束规则定义在xml文档中
外部dtd:将约束的规则定义在外部的dtd文件中
    * 本地:<!DOCTYPE 根标签名 SYSTEM "dtd文件的位置">
    * 网络:<!DOCTYPE 根标签名 PUBLIC "dtd文件名字" "dtd文件的位置URL">

示例 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE students SYSTEM "student.dtd">

<students>
	<student number="D001">
		<name>tom</name>
		<age>18</age>
		<sex>male</sex>
	</student>
	
</students>

1.24.3.3.2Schema约束

比dtd 更能更加强大。 提供了更加丰富的数据类型

XML Schema 可针对未来的需求进行扩展 ​ XML Schema 更完善,功能更强大 ​ XML Schema 基于 XML 编写 (schema本质上就是一个 xml文件) ​ XML Schema 支持数据类型 (提供的更加丰富的数据类型) ​ XML Schema 支持命名空间

Schema约束编写

扩展名是:xsd

<?xml version="1.0"?>
<xsd:schema xmlns="http://www.itfxp.com/xml"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.itfxp.com/xml" elementFormDefault="qualified">
    <xsd:element name="students" type="studentsType"/>
    <xsd:complexType name="studentsType">
        <xsd:sequence>
            <xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="studentType">
        <xsd:sequence>
            <xsd:element name="name" type="xsd:string"/>
            <xsd:element name="age" type="ageType" />
            <xsd:element name="sex" type="sexType" />
        </xsd:sequence>
        <xsd:attribute name="number" type="numberType" use="required"/>
    </xsd:complexType>
    <xsd:simpleType name="sexType">
        <xsd:restriction base="xsd:string">
            <xsd:enumeration value="male"/>
            <xsd:enumeration value="female"/>
        </xsd:restriction>
    </xsd:simpleType>
    <xsd:simpleType name="ageType">
        <xsd:restriction base="xsd:integer">
            <xsd:minInclusive value="0"/>
            <xsd:maxInclusive value="256"/>
        </xsd:restriction>
    </xsd:simpleType>
    <xsd:simpleType name="numberType">
        <xsd:restriction base="xsd:string">
            <xsd:pattern value="heima_\d{4}"/>
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema> 

Schema约束引入

1.填写xml文档的根元素
2.引入xsi前缀.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3.引入xsd文件命名空间.  xsi:schemaLocation="http://www.itfxp.com/xml  student.xsd"
4.为每一个xsd约束声明一个前缀,作为标识  xmlns="http://www.itfxp.com/xml" 

<?xml version="1.0" encoding="UTF-8" ?>
<!-- 
	1.填写xml文档的根元素
	2.引入xsi前缀.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	3.引入xsd文件命名空间.  xsi:schemaLocation="http://www.itfxp.com/xml  student.xsd"
	4.为每一个xsd约束声明一个前缀,作为标识  xmlns="http://www.itfxp.com/xml" 
 -->
 <students   
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns="http://www.itfxp.com/xml" 
           xsi:schemaLocation="http://www.itfxp.com/xml  student.xsd">
 	<student number="Z0001">
 		<name>tom</name>
 		<age>18</age>
 		<sex>male</sex>
 	</student>
 </students>

1.24.3.4XML解析

操作xml文档,将文档中的数据读取到内存中

操作XML两种情况:

解析(读取):将文档中的数据读取到内存中

写入:将内存中的数据保存到xml文档中(持久化的存储)

1.24.3.4.1sax解析

(Simple API for XML)

处理方式类似于流处理,边读取边解析,采用的是事件回调的方式,书写好用于处理响应事件的方法,进行解析,当进行读取时触发相应事件,执行对应方法


//sax解析xml
public class SaxParse {
	public static void main(String[] args) throws Exception {
		// 1、调用sax解析工厂对象newInstance方法创建sax解析工厂对象
		SAXParserFactory saxFactory = SAXParserFactory.newInstance();
		// 2、调用sax工厂对象 newSAXParser方法创建sax解析对象
		SAXParser saxParse = saxFactory.newSAXParser();

		// 3、创建自定义解析器对象
		MySaxHandler mh=new MySaxHandler();
		// 4、使用解析对象传入自定义解析器与解析地址解析数据
		InputStream is = SaxParse.class.getClassLoader().getResourceAsStream("文件.xml");
		saxParse.parse(is, mh);
		// 5、获取数据
		
		ArrayList<Teacher> list = mh.list;
		for (Teacher teacher : list) {
			System.out.println(teacher);
		}
		
	}
}

//sax需要自己创建解析器类解析对应的文件
//创建自定义解析器类继承默认的解析器类
//默认解析器类实现了方法但是没有书写任何方法体
class MySaxHandler extends DefaultHandler{
	//startElement
    //当读取到起始标签时回调的方法
    //endElement
    //当读取到结束标签时回调的方法
    //characters
    //当读取到文本标签时回调的方法
    //在sax解析中是按照标签进行解析
    //起始标签 结束标签  文本标签
	String str="";
	//创建集合保存所有teacher对象数据
	public ArrayList<Teacher> list=new ArrayList<>();
	Teacher t;//保存每次读取数据的teacher对象
	
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		 //当读取到teacher起始标识时创建teacher对象
		if(qName.equals("teacher")){
			 t=new Teacher();
		 }
	}
	

	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		//当读取到teacher结束表情时将teacher对象加入集合
		if(qName.equals("teacher")){
			list.add(t);
		}else{
			//如果不是对象的结束标签
			//判断是否是属性结束标签
			if(qName.equals("name")){
				t.setName(str);
			}else if(qName.equals("age")){
				t.setAge(Integer.valueOf(str));
			}else if(qName.equals("sex")){
				t.setSex(str);
			}
		}
	}
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		str=new String(ch,start,length);
	}
}

1.24.3.4.2dom解析

(Document Object Model)

解析方式基于数据的节点层次结构进行解析,解析方式类可以理解为内嵌了处理器,在进行加载时使用已经提供的方式进行数据的解析,并以一定的层次结构进行保存,提供相应的方法可以直接进行数据的获取

dom解析采用的是默认处理器预处理形式进行解析,可以理解为执行时会先读取解析一遍数据,并将所有数据按照默认的格式进行存储

//dom解析xml
public class DomParse {
	public static void main(String[] args) throws Exception {
		//1、使用dom解析工厂类newInstance方法创建dom解析工厂对象
		DocumentBuilderFactory DomFactory=DocumentBuilderFactory.newInstance();
		//2、使用dom解析工厂对象newDocumentBuilder方法创建dom解析对象
		DocumentBuilder domParse = DomFactory.newDocumentBuilder();
		//3、使用dom解析对象方法解析指定的流,获取存储当前文档数据的Document对象
		InputStream is = SaxParse.class.getClassLoader().getResourceAsStream("com/bl/test.xml");
		// dom里面就存的xml里的所有标签和内容  以便于通过标签名获取指定标签
        Document dom = domParse.parse(is);
		//4、调用Document类提供的方法从Document对象中获取指定数据
		
		//通过标签名获取指定标签
		//会方法当前xml中所有对应标签的对象数据
		NodeList teacherList = dom.getElementsByTagName("teacher");
		//NodeList 是其自定义的类似于集合的数据容器
		ArrayList<Teacher> list=new ArrayList<>();//创建存储数据的集合
		for (int i = 0; i < teacherList.getLength(); i++) {
			Teacher t=new Teacher();
			//获取每个teacher标签
			//item获取对应索引标签
			Node teacher = teacherList.item(i);
			//getChildNodes获取当前标签下的所有子标签
			NodeList fieldList = teacher.getChildNodes();
				for (int j = 0; j < fieldList.getLength(); j++) {
					//获取当前teacher标签中对应的属性标签
					Node field = fieldList.item(j);
					//获取当前属性标签对应数据的值
					if(!field.getNodeName().equals("#text")){
						String nodeValue = field.getFirstChild().getNodeValue();
						if(field.getNodeName().equals("name")){
							t.setName(nodeValue);
						}else if(field.getNodeName().equals("age")){
							t.setAge(Integer.valueOf(nodeValue));
						}else if(field.getNodeName().equals("sex")){
							t.setSex(nodeValue);
						}
					}
				}
			list.add(t);
		}
		
		 for (Teacher teacher : list) {
			System.out.println(teacher);
		}
	}
}

1.24.3.4.3jdom解析

(Java-based Document Object Model)

基于java规范开发的dom方式解析xml数据,主要是基于javaAPI与集合修改了原本的nodeList存储节点的形式,与dom原有的API。

JDOM文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)

JDOM自身不包含解析器。它通常使用SAX2解析器来解析和验证输入XML文档(尽管它还可以将以前构造的DOM表示作为输入)。

public class JDomParse {

    //jdom不能使用dom原有的解析
    //使用的是sax2的解析

    public static void main(String[] args) throws Exception {
        //1创建sex解析器new SAXBuilder
        SAXBuilder saxBuilder = new SAXBuilder();
        //2使用sex解析解析数据build
        InputStream resourceAsStream = DomParse.class.getClassLoader().getResourceAsStream("com/bl/Students.xml");
        Document dom = saxBuilder.build(resourceAsStream);
        //3使用jdomAPI进行数据的获取
        Element rootElement = dom.getRootElement();//获取代表根节点标签的元素对象
        List<Element> studentList = rootElement.getChildren();
        ArrayList<Student> list = new ArrayList<>();
        for (Element student : studentList) {
            Student s = new Student();
            List<Element> filedList = student.getChildren();
            for (Element filed : filedList) {
                String qName = filed.getName();
                if (qName.equals("name")) {
                    s.setName(filed.getValue());
                } else if (qName.equals("age")) {
                    s.setAge(Integer.valueOf(filed.getValue()));
                } else if (qName.equals("sex")) {
                    s.setSex(filed.getValue());
                }
               // System.out.println(filed.getName() + ":" + filed.getValue());
            }
            list.add(s);
        }
        System.out.println(list);
    }
}

1.24.3.4.4dom4j解析

DOM4J是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML,为解决jdom简化API导致的灵活性问题,dom4j在其基础上添加了大量的API功能代码。

public class Dom4JParse {
    //不能直接使用dom解析器
    //需要使用sex的解析器进行解析读取
    public static void main(String[] args) throws Exception {
        //创建sax解析器对象 new SAXReader
        SAXReader saxReader=new SAXReader();
        //解析响应的数据read
        InputStream resourceAsStream = DomParse.class.getClassLoader().getResourceAsStream("com/bl/Students.xml");
        Document dom = saxReader.read(resourceAsStream);
        //使用dom4j 提供的API进行获取
        Element students = dom.getRootElement();//获取根节点元素对象
        Iterator studentIterator = students.elementIterator();
        ArrayList<Student> list = new ArrayList<>();
        while(studentIterator.hasNext()){
            Student s = new Student();
            Element student = (Element) studentIterator.next();
            Iterator fieldIterator = student.elementIterator();
            while(fieldIterator.hasNext()){
                Element field = (Element)fieldIterator.next();
                //System.out.println(field.getName()+":"+field.getStringValue());
                String qName = field.getName();
                if (qName.equals("name")) {
                    s.setName(field.getStringValue());
                } else if (qName.equals("age")) {
                    s.setAge(Integer.valueOf(field.getStringValue()));
                } else if (qName.equals("sex")) {
                    s.setSex(field.getStringValue());
                }
            }
            list.add(s);
        }
        System.out.println(list);
    }
}


1.24.3.4.5四种解析方式的对比

sax解析

dom解析

jdom解析

dom4j解析

优点

进行解析时无需加载全部文档,可以边读取边解析

基于事件回调进行响应的解析,只有触发相应事件时才会回调相应方法

可以解析数据量大于内存的数据

底层以数据节点的形式进行存储数据,提供相应的方法快速获取

可以对某一标签直接进行访问

将数据存储使用集合的形式存储

简化API的使用

提高了大量的API应用于各种形式的使用
缺点

需要自己维护响应事件的回调方法,随文档的复杂度难度递增

单向解析,不会进行反向查询,只能从头解析

需要加载整个文件,消耗内存,不能处理大于内存的数据

无论是否需要都会加载整个数据

没有良好的灵活性

性能较差

API太过繁琐,如果只是进行简单的解析,不需要使用

1.24.3.4.6常见的XML解析器

  • JAXP:sun公司提供的解析器,支持dom和sax两种思想

  • DOM4J:一款非常优秀的解析器

  • Jsoup:jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

  • PULL:Android操作系统内置的解析器,sax方式的。

上一篇:1.22Java-反射
下一篇:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老李头喽

高级内容,进一步深入JA领域

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值