Day02

01-泛型

泛型(Generic) —泛形的作用

JDK5以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免就会引发程序的一些安全性问题。例如:

ArrayList list = new ArrayList();
list.add("abc");
Integer num = (Integer) list.get(0);  //运行时会出错,但编码时发现不了

list.add(new Random());
list.add(new ArrayList());
for(int i=0;i<list.size();i++){
    (?)list.get(i);          //此处取出来的对象应转换成什么类型
}
JDK5中的泛形允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定性(尤其在大型程序中更为突出)
注意:泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。
这里要注意,虽然生成的class文件中不带有泛型信息,但是在反射泛型的时候仍然可以读取到泛型,这是因为编译器在擦出泛型的时候也会将泛型信息保存到类的一特特殊地方,比如我们同样写两个名称,相同功能的代码,只是一个带泛型,一个不带泛型,它们在编译之后生成的class字节码完全相同,但是内部的某个地方带有泛型的信息
泛形的基本术语,以ArrayList<E>为例:<>念着typeof
•ArrayList<E>中的E称为类型参数变量
•ArrayList<Integer>中的Integer称为实际类型参数,泛型的实际类型参数为了对象类型,不能为基本数据类型
•整个称为ArrayList<E>泛型类型
•整个ArrayList<Integer>称为参数化的类型ParameterizedType

 

泛型典型应用

使用迭代器迭代泛形集合中的元素。
使用增强for循环迭代泛形集合中的元素。
存取HashMap中的元素。
/day02/src/cn/itcast/generic/Demo1.java
package cn.itcast.generic;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;

import org.junit.Test;

public class Demo1 {
    @Test
    //使用迭代器迭代泛型集合中的元素
    public void test1(){
        List<String> list = new ArrayList<String>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            String str = it.next();
            System.out.println(str);
        }
    }
    @Test
    //使用增强for循环迭代泛型集合中的元素
    public void test2(){
        List<String> list = new ArrayList<String>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        for(String str : list){
            System.out.println(str);
        }
    }
    @Test
    //使用的带起迭代双列集合HashMap中的元素
    public void test3(){
        HashMap<Integer,String> map = new HashMap<Integer,String>();
        map.put(1, "aaa");
        map.put(2, "bbb");
        map.put(3, "ccc");
        //迭代HashMap的第一种方法,使用keySet
        Set<Integer> set = map.keySet();
        Iterator<Integer> it = set.iterator();
        while(it.hasNext()){
            Integer key = it.next();
            String value = map.get(key);
            System.out.println(key+"->"+value);
        }
        //迭代HashMap的第二种方法,使用entrySet
        Set<Entry<Integer,String>> s = map.entrySet();
        Iterator<Entry<Integer,String>> i = s.iterator();
        while(i.hasNext()){
            Entry<Integer,String> en = i.next();
            Integer key = en.getKey();
            String value = en.getValue();
            System.out.println(key+"->"+value);
        }
    }
}

 

使用泛形时的几个常见问题:
•使用泛形时,泛形类型须为引用类型,不能是基本数据类型
•ArrayList<String> list = new ArrayList<Object>();      //这种类型是不可以的,这里要记住结论,使用泛型前后类型必须相同
•ArrayList<Object> list = new ArrayList<String>();      //这种类型也是不可以的,这里要记住结论,使用泛型前后类型必须相同
•ArrayList<String> list = new ArrayList ();           //这种类型可以,这里要记住结论,使用泛型的时候,某一边使用泛型是允许的,这个是为了兼容以前写没有泛型的程序,比便没有泛型的程序调用带有泛型的程序
•ArrayList list = new ArrayList<String>();            //这种类型可以,这里要记住结论,使用泛型的时候,某一边使用泛型是允许的,这个是为了兼容以前写没有泛型的程序,以便带有泛型的程序调用以前没有泛型的程序
/day02/src/cn/itcast/generic/Demo2.java
package cn.itcast.generic;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

//使用泛型必须牢记一个结论,如果集合要用泛型,则集合两边的泛型类型必须相同,
//泛型集合一边用泛型这个是可以的,因为这个是为了便于和以前没有泛型时的代码做交互
public class Demo2 {
    @Test
    public void test1(){
        //如果集合两边要用泛型,则泛型类型必须相同,否则出错
        //ArrayList<String> list = new ArrayList<Object>();
        //ArrayList<Object> list = new ArrayList<String>();
          ArrayList<String> list = new ArrayList<String>();
    }
    @Test
    public void test2(){
        //假如这个就代表有泛型时写的代码,为了兼容以前没有泛型时写的代码,这里可以在集合的一边写泛型
        getList1(new ArrayList<String>());
        //假如这个就代表没有泛型时写的代码
        getList2(new ArrayList());
    }
    //假如这个就代表没有泛型时写的代码
    public void getList1(List list){
        System.out.println(list);
    }
    //假如这个就代表有泛型时写的代码,这里为了兼容以前没有泛型时写的代码,这里同样可以在集合的一边写泛型
    public void getList2(List<String> list){
        System.out.println(list);
    }
    
}

自定义泛形——泛型方法

Java程序中的普通方法、构造方法和静态方法中都可以使用泛型。方法使用泛形前,必须对泛形进行声明,语法:<T> T可以是任意字母,但通常必须要大写。<T>通常需放在方法的返回值声明之前。例如:

  public static <T> void doxx(T t);      

注意:
•只有对象类型才能作为泛型方法的实际参数。
•在泛型中可以同时有多个类型,例如:

  public static <K,V> V getValue(K key) { return map.get(key);}

如果一个类多处都要用到同一个泛型,这时可以把泛形定义在类上(即类级别的泛型),语法格式如下:

  public class GenericDao<T> {

  private T field1;

  public void save(T obj){}

  public T getId(int id){}

  }

注意,静态方法不能使用类定义的泛形,而应单独定义泛形。

 /day02/src/cn/itcast/generic/Demo3.java

package cn.itcast.generic;

import org.junit.Test;

public class Demo3 {
    //某个方法中要使用泛型则必须先定义,泛型要放在返回值之前
    public static <T> void test1(T t){
        
    }
    //如果某个方法中要使用多个泛型,则都需要先定义
    //下面这个方法就是传递一个T类型的泛型变量,返回一个V类型的泛型变量
    public static <T,V> V test2(T t){
        return null;
    }
}
//如果某个类中多个地方使用到同一个泛型,我们就可以将这个泛型定义在类上
//但是这里注意,静态方法不能使用类定义的泛型,它必须单独定义泛型
class Demo<T>{
    
}

 

 ————————————————————————————————————————————————————————————————————

 02-xml语法

什么是XML

Extensible Markup Language,翻译过来为可扩展标记语言。Xml技术是w3c组织发布的,目前推荐遵循的是W3C组织于2000发布的XML1.0规范。  

XML技术用于解决什么问题

XML语言出现的根本目标在于描述上图那种,在现实生活中经常出现的有关系的数据。
XML语言中,它允许用户自定义标签。一个标签用于描述一段数据;一个标签可分为开始标签和结束标签,在开始标签和结束标签之间,又可以使用其它标签描述其它数据,以此来实现数据关系的描述。例如:
<?xml version="1.0" encoding="UTF-8"?>

<中国>
    <北京>
        <海淀></海淀>
        <丰台></丰台>
    </北京>
    <湖南>
        <长沙></长沙>
        <岳阳></岳阳>
    </湖南>
    <湖北>
        <武汉></武汉>
        <荆州></荆州>
    </湖北>
</中国>
XML技术除用于保存有关系的数据之外,它还经常用作软件配置文件,以描述程序模块之间的关系。
在一个软件系统中,为提高系统的灵活性,它所启动的模块通常由其配置文件决定

XML语法

一个XML文件分为如下几部分内容:
•文档声明
•元素
•属性
•注释 
•CDATA区 、特殊字符
•处理指令(processing instruction)

XML语法-文档声明

在编写XML文档时,需要先使用文档声明,声明XML文档的类型。
最简单的声明语法:

  <?xml version="1.0" ?>

encoding属性说明文档的字符编码:

  <?xml version="1.0" encoding="GB2312" ?> 

standalone属性说明文档是否独立:

  <?xml version="1.0" encoding="GB2312"  standalone="yes" ?>

常见错误:

1. <?xml version=1.0 ?>    //忘记了"",或者写成中文的“”,应该是version="1.0"

2. <?xml version=“1.0” ?>   //空格写成了tab打空格,这个最恶心

3.编码错误            //申明的字符集编码和保存的字符集编码不相同,这里要特别注意在MyEclipse中你申明的是什么字符集就会给你保存成什么样的字符集文件,但是如果你用记事本或者其它编辑器写的xml,虽然你在声明中写了字符集编码,但是在保存时必须注意要保存成对应的字符集编码,不然浏览器打不来xml(要报无效的字符错误),比如我在xml中声明浏览器用UTF-8的字符集打开xml文件,但是在保存时,编辑器会默认用本地字符集编码保存(也就是GB2312),这就会导致无效的字符错误

<?xml version="1.0" encoding="UTF-8"?>
<xml-simple>
 <a>美国</a>
 <b>中国</b>
</xml-simple>

 

 

将保存的字符集修改为UTF-8则浏览器显示正常

 

 XML语法-元素

XML元素指XML文件中出现的标签,一个标签分为开始标签和结束标签,一个标签有如下几种书写形式,例如:
•包含标签体:<a>www.itcast.cn</a>
•不含标签体的:<a></a>, 简写为:<a/>
一个标签中也可以嵌套若干子标签。但所有标签必须合理的嵌套,绝对不允许交叉嵌套 ,例如:

  <a>welcome to <b>www.it315.org</a></b>

格式良好的XML文档必须有且仅有一个根标签,其它标签都是这个根标签的子孙标签

 

对于XML标签中出现的所有空格和换行,XML解析程序都会当作标签内容进行处理。例如:下面两段内容的意义是不一样的。

 

由于在XML中,空格和换行都作为原始内容被处理,所以,在编写XML文件时,使用换行和缩进等方式来让原文件中的内容清晰可读的“良好”书写习惯可能要被迫改变。

 

一个XML元素可以包含字母、数字以及其它一些可见字符,但必须遵守下面的一些规范:
•区分大小写,例如,<P><p>是两个不同的标记。
不能以数字或"_" (下划线)开头。
不能以xml(XML、或Xml )开头。
不能包含空格。
名称中间不能包含冒号(:)。

 

 XML语法-属性

一个标签可以有多个属性,每个属性都有它自己的名称和取值,例如:

  <input name=“text”>

属性值一定要用双引号(")或单引号(')引起来
定义属性必须遵循与标签相同的命名规范
多学一招:在XML技术中,标签属性所代表的信息,也可以被改成用子元素的形式来描述,例如:
<input>
     <name>text</name>
</input>

 XML语法-注释

Xml文件中的注释采用:“<!--注释-->” 格式。
l注意:
•XML声明之前不能有注释
•注释不能嵌套,例如:

  <!--大段注释

  ……

  <!--局部注释-->

  ……

  -->  

 

 XML语法-CDATA区

在编写XML文件时,有些内容可能不想让解析引擎解析执行,而是当作原始内容处理。
遇到此种情况,可以把这些内容放在CDATA区里,对于CDATA区域内的内容,XML解析程序不会处理,而是直接原封不动的输出。
语法:<![CDATA[ 内容 ]]>

  <![CDATA[

  <itcast>

  <br/>

  </itcast>

  ]]>

<?xml version="1.0" encoding="UTF-8"?>
<xml-simple>
 <![CDATA[
    <a>
     美国
    </a>
 ]]>
 <b>中国</b>
</xml-simple>

 

浏览器中输出结果

 XML语法-转义字符

 对于一些单个字符,若想显示其原始样式,也可以使用转义的形式予以处理。

 

 

 XML语法-处理指令

处理指令,简称PI processing instruction)。处理指令用来指挥解析引擎如何解析XML文档内容。
例如,在XML文档中可以使用xml-stylesheet指令,通知XML解析引擎,应用css文件显示xml文档内容。  <?xml-stylesheet type="text/css" href="1.css"?>
处理指令必须以“<?”作为开头,以“?>”作为结尾,XML声明语句就是最常见的一种处理指令。 

 1.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="1.css"?>
<xml-simple>
 <a id="a">中国</a>
 <b id="b">美国</b>
 <c id="c">英国</c>
 <d id="d">日本</d>
</xml-simple>

1.css 

#a{
 color:red;
 font-size:20px;
}
#b{
 color:blue;
 font-size:15px;
}
#c{
 color:yellow;
 font-size:10px;
}
#d{
 color:balck;
 font-size:5px;
}

 

 结果

 

---------------------------------------------------------------------------------------------------------------------------------------

 03-dtd约束

XML约束

XML约束概述

什么是XML约束
•在XML技术里,可以编写一个文档来约束一个XML文档的书写规范,这称之为XML约束。
为什么需要XML约束
原因是在一些框架中的配置都是基于xml配置文件的,作者为了避免用户在xml配置文件中乱写,这个时候就必须对xml配置文件做限定约束
用户只有写入规定的类型的数据才不回报错
常用的约束技术
•XML DTD      //这个技术正在慢慢在淘汰
•XML Schema    //这个技术我们将在稍后讲解

 

DTD约束快束入门 

DTD(Document Type Definition),全称为文档类型定义。
注意这里的xml文件必须保存为UTF-8的文件

book.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE 书架 SYSTEM "book.dtd">
<书架>
    <>
        <书名>Java就业培训教程</书名>
        <作者>张孝祥</作者>
        <售价>39.00元</售价>
    </>
    <>
        <书名>JavaScript网页开发</书名>
        <作者>张孝祥</作者>
        <售价>28.00元</售价>
    </>
</书架>

DTD文件应保存为UTF-8Unicode的文件

book.dtd

<!ELEMENT 书架 (书+)>
    <!ELEMENT 书 (书名,作者,售价)>
    <!ELEMENT 书名 (#PCDATA)>
    <!ELEMENT 作者 (#PCDATA)>
    <!ELEMENT 售价 (#PCDATA)>

<!ELEMENT 书架 (书+)>  //这个表示书架这个元素标签中可以放多个书标签

<!ELEMENT 书 (书名,作者,售价)>  //这句话表示书这个元素标签只能方法书名,作者,售价这个三个标签,其它的不能方法

<!ELEMENT 书名 (#PCDATA)>    //这个表示书名这个元素标签只能放#PCDATA
<!ELEMENT 作者 (#PCDATA)>    //这个表示作者这个元素标签只能放#PCDATA
<!ELEMENT 售价 (#PCDATA)>    //这个表示售价这个元素标签只能放#PCDATA

#PCDATA  翻译过来就是parse character date,也就是可解析的字符数据(说白了就是字符串)

 

这里要注意一个问题,现在的IE以及不验证DTD文件,我们可以通过MyEclipse来校验xml和dtd文件的对应是否正确

 

编写DTD约束的两种方式 

 DTD约束即可以作为一个单独的文件编写,也可以在XML文件内编写

 在xml文件内编写DTD

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE 书架 [
    <!ELEMENT 书架 (书+)>
    <!ELEMENT 书 (书名,作者,售价)>
    <!ELEMENT 书名 (#PCDATA)>
    <!ELEMENT 作者 (#PCDATA)>
    <!ELEMENT 售价 (#PCDATA)>
]>
<书架>
    <>
        <书名>Java就业培训教程</书名>
        <作者>张孝祥</作者>
        <售价>39.00元</售价>
    </>
    <>
         <书名>JavaScript网页开发</书名>
         <作者>张孝祥</作者>
         <售价>28.00元</售价>
     </>
</书架>
                

 

 引用DTD约束

XML文件使用 DOCTYPE 声明语句来指明它所遵循的DTD文件,DOCTYPE声明语句有两种形式:
•当引用的文件在本地时,采用如下方式:

  <!DOCTYPE 文档根结点 SYSTEM "DTD文件的URL">

  例如: <!DOCTYPE 书架 SYSTEM “book.dtd”>。在xml文件中手写一下。

•当引用的文件是一个公共的文件时,采用如下方式: 

  <!DOCTYPE 文档根结点 PUBLIC "DTD名称" "DTD文件的URL">

    例如:<!DOCTYPE web-app PUBLIC

  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

  "http://java.sun.com/dtd/web-app_2_3.dtd">

 

 DTD约束语法细节

•元素定义
•属性定义
•实体定义

DTD 的语法细节:元素定义 

在DTD文档中使用ELEMENT声明一个XML元素,语法格式如下所示:

   <!ELEMENT 元素名称 元素类型>

元素类型可以是元素内容、或类型
•如为元素内容:则需要使用()括起来,如

<!ELEMENT 书架 (书名,作者,售价)>

<!ELEMENT 书名 (#PCDATA)>

•如为元素类型,则直接书写,DTD规范定义了如下几种类型:
  EMPTY:用于定义空元素,例如<br/> <hr/>
  ANY:表示元素内容为任意类型。DTD 的语法细节:元素定义 
 
元素内容中可以使用如下方式,描述内容的组成关系
•用逗号分隔,表示内容的出现顺序必须与声明时一致。<!ELEMENT MYFILE (TITLE,AUTHOR,EMAIL)>
• 用|分隔,表示任选其一,即多个只能出现一个。<!ELEMENT MYFILE (TITLE|AUTHOR|EMAIL)>
在元素内容中也可以使用+、*、?等符号表示元素出现的次数:

  +: 一次或多次 (+)

   ?: 0次或一次 (?)

   *: 0次或多次  (书*)

也可使用圆括号( )批量设置,例

  <!ELEMENT MYFILE ((TITLE*, AUTHOR?, EMAIL)* | COMMENT)>

 

 属性定义

xml文档中的标签属性需通过ATTLIST为其设置属性
语法格式:

  <!ATTLIST 元素名

  属性名1 属性值类型 设置说明

  属性名2 属性值类型 设置说明

  ……

  >

属性声明举例:

<!ATTLIST 商品

  类别 CDATA #REQUIRED    //#REQUIRED表示这个类型是必须的

  颜色 CDATA #IMPLIED     //#IMPLIED表示这个类型是可选择的

>

对应XML文件:

  <商品 类别="服装" 颜色="黄色">…</商品>

  <商品 类别="服装">…</商品

 

设置说明:
•#REQUIRED:必须设置该属性
•#IMPLIED:可以设置也可以不设置
•#FIXED:说明该属性的取值固定为一个值,在 XML 文件中不能为该属性设置其它值。但需要为该属性提供这个值
•直接使用默认值:在 XML 中可以设置该值也可以不设置该属性值。若没设置则使用默认值。 

 

举例:
      <!ATTLIST 页面作者 
         姓名 CDATA #IMPLIED         #这里的姓名也是可选的 
         年龄 CDATA #IMPLIED         #这里的年龄是可选的 
         联系信息 CDATA #REQUIRED      #这里的联系信息是必须要写的
         网站职务 CDATA #FIXED "页面作者"  #这里的网站职务是固定的,只能是页面作者 
         个人爱好 CDATA "上网"        #这里的个人爱好的默认值就是上网
       > 

 

 常用属性值类型

•CDATA表示属性值为普通文本字符串
ENUMERATED
ID
ENTITY(实体)

 属性值类型-ENUMERATED

<?xml version = "1.0" encoding="GB2312" standalone="yes"?>
<!DOCTYPE 购物篮 [
    <!ELEMENT 肉 EMPTY>
    <!ATTLIST 肉 品种 ( 鸡肉 | 牛肉 | 猪肉 | 鱼肉 ) "鸡肉">    //这里就为肉这个标签定义了一个属性(品种),然后品种的属性值为一个枚举,默认值是鸡肉
]> 
<购物篮>
    <肉 品种="鱼肉"/>
    <肉 品种="牛肉"/>
    </>            //这个没有写品种这个属性,它默认的值
</购物篮>

 属性值类型-ID

表示属性的设置值为一个唯一值,不能重复
ID 属性的值只能由字母,下划线开始,不能出现空白字符
<?xml version = "1.0" encoding="GB2312" ?>

<!DOCTYPE 联系人列表[
    <!ELEMENT 联系人列表 ANY>
    <!ELEMENT 联系人(姓名,EMAIL)>
    <!ELEMENT 姓名(#PCDATA)>
    <!ELEMENT EMAIL(#PCDATA)>
    <!ATTLIST 联系人 编号 ID #REQUIRED>
]>

<联系人列表>
    <联系人 编号="a1">      #这里的编号="a1"就是唯一的,整个xml中就只有这一个,还要注意一点如果类型为ID,则不能以数字开头,所以这里不能是编号="1"
        <姓名>张三</姓名>
        <EMAIL>zhang@it315.org</EMAIL>
     </联系人>
    <联系人 编号="a2">
        <姓名>李四</姓名>
        <EMAIL>li@it315.org</EMAIL>
    </联系人>
</联系人列表>

 

 属性值类型-实体定义  

实体用于为一段内容创建一个别名,以后在XML文档中就可以使用别名引用这段内容了。
DTD定义中,一条<!ENTITY …>语句用于定义一个实体。

实体可分为两种类型:引用实体和参数实体

 实体定义-引用实体  

引用实体主要在 XML 文档中被应用
语法格式:
•<!ENTITY 实体名称 “实体内容” >:直接转变成实体内容
引用方式:

&实体名称;

举例:

book.dtd

<!ENTITY bookname "Java就业培训教程">    #这里在dtd中定义了一个实体
<!ELEMENT 书架 (书+)>
    <!ELEMENT 书 (书名,作者,售价)>
    <!ELEMENT 书名 (#PCDATA)>
    <!ELEMENT 作者 (#PCDATA)>
    <!ELEMENT 售价 (#PCDATA)>

book.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE 书架 SYSTEM "book.dtd">
<书架>
    <>
        <书名>&bookname;</书名>    <!--这里在xml中引用了实体-->
        <作者>张孝祥</作者>
        <售价>39.00元</售价>
    </>
    <>
        <书名>JavaScript网页开发</书名>
        <作者>张孝祥</作者>
        <售价>28.00元</售价>
    </>
</书架>

 

 实体定义-参数实体  

参数实体只能在 DTD 文件自身使用
语法格式:

   <!ENTITY % 实体名称 "实体内容" >

引用方式:

%实体名称;

举例1
 <!ENTITY % TAG_NAMES "姓名 | EMAIL | 电话 | 地址">
    
 <!ELEMENT 个人信息 (%TAG_NAMES; | 生日)>
 <!ELEMENT 客户信息 (%TAG_NAMES; | 公司名)>

 举例2:

<!ENTITY % common.attributes
     " id ID #IMPLIED 
    account CDATA #REQUIRED "
>
...
<!ATTLIST purchaseOrder %common.attributes;>    #这里通过参数实体为purchaseOrder这个标签定义属性名id和account
<!ATTLIST item %common.attributes;>         #这里也一样,id的这个id的属性值为ID,设置说明#IMPLIED,这里的account属性名的属性值类型是CDATA,设置说明是#REQUIRED

 

 *****************

以上我们就学完了DTD了,但是到这里还是没有底,这里为了加强我们就去阅读dtd帮助文档,这个文档中有很多dtd的实例,我们现在就来阅读DTD文档

中的例子,并写出例子

 GATALOG.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE CATALOG [

    <!ENTITY AUTHOR "John Doe">
    <!ENTITY COMPANY "JD Power Tools, Inc.">
    <!ENTITY EMAIL "jd@jd-tools.com">
    
    <!ELEMENT CATALOG (PRODUCT+)>
    
    <!ELEMENT PRODUCT
    (SPECIFICATIONS+,OPTIONS?,PRICE+,NOTES?)>
    <!ATTLIST PRODUCT
    NAME CDATA #IMPLIED
    CATEGORY (HandTool|Table|Shop-Professional) "HandTool"
    PARTNUM CDATA #IMPLIED
    PLANT (Pittsburgh|Milwaukee|Chicago) "Chicago"
    INVENTORY (InStock|Backordered|Discontinued) "InStock">
    
    <!ELEMENT SPECIFICATIONS (#PCDATA)>
    <!ATTLIST SPECIFICATIONS
    WEIGHT CDATA #IMPLIED
    POWER CDATA #IMPLIED>
    
    <!ELEMENT OPTIONS (#PCDATA)>
    <!ATTLIST OPTIONS
    FINISH (Metal|Polished|Matte) "Matte" 
    ADAPTER (Included|Optional|NotApplicable) "Included"
    CASE (HardShell|Soft|NotApplicable) "HardShell">
    
    <!ELEMENT PRICE (#PCDATA)>
    <!ATTLIST PRICE
    MSRP CDATA #IMPLIED
    WHOLESALE CDATA #IMPLIED
    STREET CDATA #IMPLIED
    SHIPPING CDATA #IMPLIED>
    
    <!ELEMENT NOTES (#PCDATA)>

]>
<CATALOG>
    <PRODUCT>
        <SPECIFICATIONS>xxxx</SPECIFICATIONS>
        <PRICE>xxxx</PRICE>
    </PRODUCT>
</CATALOG>

 

 更多实例请参照DTD.chm文档

 -------------------------------------------------------------------------------------------------------------------------------------

 04-xml编程

 XML解析技术概述

XML解析方式分为两种:dom和sax
•dom:(Document Object Model, 即文档对象模型) 是 W3C 组织推荐的处理 XML 的一种方式。
•sax: (Simple API for XML) 不是官方标准,但它是 XML 社区事实上的标准,几乎所有的 XML 解析器都支持它。
DOM解析的特点
•1.在dom解析下,它会把整个xml文件装到内存中,并把文档中的每一部分内容都变成一个个对象,并按照文档的结构建立起对象的关系,在dom解析下,对文档的CRUD特别方便
•2.缺点:在xml文档很大的话,dom方式消耗的内存很大,并且容易导致内存溢出
SAX解析的特点
•1边解析边执行,它对内存的消耗很少,并且解析速度快
•2.缺点:在sax方式下不能对文档增删改

 

 

 /day02/src/cn/itcast/xml/Demo1.java

package cn.itcast.xml;

public class Demo1 {

    public static void main(String[] args) {
        //这个字节数组的大小是1G,但是一运行就会出现内存溢出的错误
        byte[] b = new byte[1024*1024*1024];

    }
}

 

 

java虚拟机的的内存默认大小是64M,一旦超过它就会内存溢出,这个我们可以从java API文档中的java模块的非标准介绍中就可以知道

当然我们可以更改java虚拟机的内存大小,方法如下

在需要运行的程序上点击右键,选择Run as,然后Open Run Dialog

然后选择Arguments

在VM arguments中输入java非标准介绍中提高的最大内存值

我们这里给java虚拟机1G的内存,我们这里给大些,给1.2G

然后就可以运行我们开始的那个程序了

/day02/src/cn/itcast/xml/Demo1.java

package cn.itcast.xml;

public class Demo1 {

    public static void main(String[] args) throws InterruptedException {
        //这个字节数组的大小是1G,但是一运行就会出现内存溢出的错误
        byte[] b = new byte[1024*1024*1024];
        //通过休眠1分钟,可以很清楚的在任务管理器中查看到1个的内存被分配了
        Thread.sleep(100000);
        System.out.println("haha");
    }

}

 

其实在命令行窗口的指令为

XML解析器
•Crimson(sum开发的)、Xerces(ibm开发的) 、Aelfred2(dom4j开发的)

 

XML解析开发包
所谓的解析开发包就是解析器所用的解析程序
Jaxp(sun)    //它用的解析器是Xerces(ibm开发的)
Jdom(jdom)   //它用的解析器是Aelfred2(dom4j开发的)
dom4j(dom4j)  //它用的解析器是Aelfred2(dom4j开发的)

 

 下面我们就介绍jaxp开发包

 JAXP

JAXP 开发包是J2SE的一部分,它由javax.xmlorg.w3c.dom org.xml.sax 包及其子包组成,所以我们在开发的时候就不用导入包
javax.xml.parsers 包中,定义了几个工厂类,程序员调用这些工厂类,可以得到对xml文档进行解析的 DOM SAX 的解析器对象。

 使用JAXP进行DOM解析

javax.xml.parsers 包中的DocumentBuilderFactory用于创建DOM模式的解析器对象 , DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance方法 ,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。
 
调用 DocumentBuilderFactory.newInstance() 方法得到创建 DOM 解析器的工厂。

 

 

 
调用工厂对象的 newDocumentBuilder方法得到 DOM 解析器对象。我们发现这个DocumentBuilder是一个抽象类
但是在它的说明里面有这样一句话,此类实例可以从DocumentBuilderFactory.newDocumentBuilder()方法获取
所以我们这里得到的其实是一个DocumentBuilder的实例
接着我们就可以调用 DOM 解析器对象的 parse() 方法解析 XML 文档,得到代表整个文档的 Document 对象,进行可以利用DOM特性对整个XML文档进行操作了。这里必须注意导入包Document包时必须导入w3c的包,因为dom编程是w3c组织贡献的

 

 /day02/src/cn/itcast/xml/Demo2.java

package cn.itcast.xml;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

public class Demo2 {

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        //创建一个DOM解析工程
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //调用工程对象的newDocumentBuider()方法得到DOM解析器
        DocumentBuilder parser = factory.newDocumentBuilder();
        //通过DOM解析器解析XML,可以得到一个文档对象模型
        File f = new File("src/book.xml");
        Document document = parser.parse(f);        //这里不要倒错包,dom编程是w3c组织提供的,所以这里必须导入org.w3c.dom.Document
        System.out.println(document.getBaseURI());
    }

}

 

DOM模型(document object model)

•DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)。
在dom中,节点之间关系如下:
•位于一个节点之上的节点是该节点的父节点(parent)
•一个节点之下的节点是该节点的子节点(children)
•同一层次,具有相同父节点的节点是兄弟节点(sibling)
•一个节点的下一个层次的节点集合是节点后代(descendant)
•父、祖父节点及所有位于节点上面的,都是节点的祖先(ancestor) 

Node对象

Node对象提供了一系列常量来代表结点的类型,当开发人员获得某个Node类型后,就可以把Node节点转换成相应的节点对象(Node的子类对象),以便于调用其特有的方法。(查看API文档)
Node对象提供了相应的方法去获得它的父结点或子结点。编程人员通过这些方法就可以读取整个XML文档的内容、或添加、修改、删除XML文档的内容了。

 

下面我们就来查找一个节点

首先我们通过DOcument的getElementsByTagName(String tagname)方法获取到想要的节点,这个方法返回的是一个集合,集合里保存的是我们要的节点

我们发现NodeList是一个接口,其实我们调用getElementsByTagName这个方法其实是返回的一个NodeList的实例,所以我们可以直接使用它的方法

 /day02/src/book.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE 书架 SYSTEM "book.dtd">
<书架>
    <>
        <书名>&bookname;</书名>
        <作者>张孝祥</作者>
        <售价>39.00元</售价>
    </>
    <>
        <书名>JavaScript网页开发</书名>
        <作者>张孝祥</作者>
        <售价>28.00元</售价>
    </>
</书架>

/day02/src/book.dtd

<!ENTITY bookname "Java就业培训教程">    
<!ELEMENT 书架 (书+)>
    <!ELEMENT 书 (书名,作者,售价)>
    <!ELEMENT 书名 (#PCDATA)>
    <!ELEMENT 作者 (#PCDATA)>
    <!ELEMENT 售价 (#PCDATA)>

 

 /day02/src/cn/itcast/xml/Demo2.java

package cn.itcast.xml;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class Demo2 {

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        //创建一个DOM解析工程
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //调用工程对象的newDocumentBuider()方法得到DOM解析器
        DocumentBuilder parser = factory.newDocumentBuilder();
        //通过DOM解析器解析XML,可以得到一个文档对象模型
        File f = new File("src/book.xml");
        Document document = parser.parse(f);        //这里不要倒错包,dom编程是w3c组织提供的,所以这里必须导入org.w3c.dom.Document
        find(document);
    }
    //查找某个节点,我们现在来查找book.xml中第一个节点<作者>张孝祥</作者>,获取到张孝祥
    public static  void find(Document document){
        //获取到DOM中所有名称为作者的节点,返回的是一个集合
        NodeList list = document.getElementsByTagName("作者");
        //得到第1个作者节点
        Node node = list.item(0);
        //获取到此节点的内容
        String name = node.getTextContent();
        System.out.println(name);
    }
}

现在我们来添加一个节点

首先我们要为某个节点添加一个子节点,需要先将这个子节点创建出来

我们可以通过Document对象的createElement(String tagName)方法创建一个节点

这虽然Document是一个接口,但是我们传递进来的是一个Docuement实现类

 

 创建好之后我们还要找到父类节点,然后在父类节点下添加子节点

 之后我们还要将修改后的document写入到xml文件中去,因为之前的更改都是更改内存中的document对象

这里我们想将docuent写入到文件中去需要一个转换器TransformerFactory

它也是一抽象类,可以通过它的newInstance()方法获取到它的实例对象

 之后在通过它的newTransformer()得到一个转换器

 通过转换器得到的是一个Transformer,虽然Transformer又是一个抽象类

但我们这里得到的却是它的一个实例

 

我们可以通过Transformer的transform(Source xmlSource, Result outputTarget)方法将内存中的document写入到xml文件中

这里要注意目标资源我们用的是DOMSource,我们可以通过它的构造方法DOMSource(Node n) ,将document传入

 

 

 

 然后结果文件我们用的是SteamResult,我们可以通过它的构造方法StreamResult(File f)

将目标xml地址吸入

 

 

 /day02/src/book.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?><书架>
    <>
        <书名>Java就业培训教程</书名>
        <作者>张孝祥</作者>
        <售价>39.00元</售价>
    </>
    <>
        <书名>JavaScript网页开发</书名>
        <作者>张孝祥</作者>
        <售价>28.00元</售价>
    </>
</书架>

/day02/src/book.dtd

<!ENTITY bookname "Java就业培训教程">    
<!ELEMENT 书架 (书+)>
    <!ELEMENT 书 (书名,作者,售价)>
    <!ELEMENT 书名 (#PCDATA)>
    <!ELEMENT 作者 (#PCDATA)>
    <!ELEMENT 售价 (#PCDATA)>

/day02/src/cn/itcast/xml/Demo2.java

package cn.itcast.xml;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class Demo2 {

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, TransformerException {
        //创建一个DOM解析工程
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //调用工程对象的newDocumentBuider()方法得到DOM解析器
        DocumentBuilder parser = factory.newDocumentBuilder();
        //通过DOM解析器解析XML,可以得到一个文档对象模型
        File f = new File("src/book.xml");
        Document document = parser.parse(f);        //这里不要倒错包,dom编程是w3c组织提供的,所以这里必须导入org.w3c.dom.Document
        //find(document);
        add(document);
    }
/*    //查找某个节点,我们现在来查找book.xml中第一个节点<作者>张孝祥</作者>,获取到张孝祥
    public static  void find(Document document){
        //获取到DOM中所有名称为作者的节点,返回的是一个集合
        NodeList list = document.getElementsByTagName("作者");
        //得到第1个作者节点
        Node node = list.item(0);
        //获取到此节点的内容
        String name = node.getTextContent();
        System.out.println(name);
    }*/
    //添加一个节点,我们要为book.xml中的第一本书添加一个内部价格
    public static void add(Document document) throws TransformerException{
        //第一步我们创建出一个节点,并为这个节点附上内容
        Node price = document.createElement("内部价格");
        price.setTextContent("10元");
        //第二步查找到我们想要将节点插入的父节点
        NodeList list = document.getElementsByTagName("书");
        Node book = list.item(0);
        book.appendChild(price);    //将子节点(内部价格)添加到父类节点(书)下(这个是直接在父类节点下添加)
        //这里注意,如果想将节点添加到某个节点的某个位置上,则需要指定一个参照节点,
        //比如我这里要将内部价格添加到作者节点的上面,则需要先将作者节点找到
        //然后通过父类节点(书)的相对插入方法insertBefor
        Node author = document.getElementsByTagName("作者").item(0);
        book.insertBefore(price, author);
        //第三步,将更新后的document写入到xml文件中
        //注意上面的更改只是将内存中的document更改了,所以这里我们要将内存中的document写入到xml文件中去
        //先得到一个转换工厂类
        TransformerFactory factory = TransformerFactory.newInstance();
        //得到一个转换器
        Transformer transformer =factory.newTransformer();
        //开始将document转换到xml文件中去
        //这里要注意,我们用的Source资源是DOMSource,我们用的目标结果是StringResult
        transformer.transform(new DOMSource(document), new StreamResult(new File("src/book.xml")));
        System.out.println("添加节点成功");
    }
}

 

 ——————————————————————————————————————————————————————————————————

 05-xml编程2

更新某个节点和删除某个节点

要删除某个节点的时候,我们必须要先得到要删除节点的父类节点

得到父类节点有两种方式,一种是直接通过document得到,另一种使用过要删除节点通过getParentNode()获取到

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<书架>
    <>
        <书名>Java就业培训教程</书名>
        <作者>黎活明</作者>
        <售价>39.00元</售价>
    </>
    <>
        <书名>JavaScript网页开发</书名>
        <作者>张孝祥</作者>
        <售价>28.00元</售价>
    </>
</书架>

 /day02/src/cn/itcast/xml/Demo3.java

package cn.itcast.xml;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

public class Demo3 {

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, TransformerException {
        //创建一个DOM解析工厂
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //调用工程对象的newDocumentBuider()方法得到DOM解析器
        DocumentBuilder parser = factory.newDocumentBuilder();
        //通过DOM解析器解析XML,可以得到一个文档对象模型
        File f = new File("src/book.xml");
        Document document = parser.parse(f);        //这里不要倒错包,dom编程是w3c组织提供的,所以这里必须导入org.w3c.dom.Document
        //update(document);
        delete(document);
    }
    //修改某个节点,这里我们修改book.xml中的第一本书的的作者为黎活明
    public static void update(Document document) throws TransformerException{
        //首先我们将需要修改的节点找到
        Node author = document.getElementsByTagName("作者").item(0);
        //从新设置作者的值
        author.setTextContent("黎活明");
        //将修改后的document写入到xml文件中去
        //先得到一个转换工厂类
        TransformerFactory factory = TransformerFactory.newInstance();
        //得到一个转换器
        Transformer transformer =factory.newTransformer();
        //开始将document转换到xml文件中去
        //这里要注意,我们用的Source资源是DOMSource,我们用的目标结果是StringResult
        transformer.transform(new DOMSource(document), new StreamResult(new File("src/book.xml")));
        System.out.println("修改节点成功");
    }
    //删除某个节点,这里我们删除第二本书,要想删除一个节点,首先要找到它的父类节点
    public static void delete(Document document) throws TransformerException{
        //首先找到要删除的节点父类节点
        Node bookshelf = document.getElementsByTagName("书架").item(0);
        //然后找到要删除的节点
        Node book = document.getElementsByTagName("书").item(1);            //其实这里可以通过子节点直接去找它的父节点,通过getParentNode这个方法去获取
        //调用父类节点的方法删除子类节点
        bookshelf.removeChild(book);
        //将修改后的document写入到xml文件中去
        //先得到一个转换工厂类
        TransformerFactory factory = TransformerFactory.newInstance();
        //得到一个转换器
        Transformer transformer =factory.newTransformer();
        //开始将document转换到xml文件中去
        //这里要注意,我们用的Source资源是DOMSource,我们用的目标结果是StringResult
        transformer.transform(new DOMSource(document), new StreamResult(new File("src/book.xml")));
        System.out.println("删除节点成功");
        
    }
}

 下面我们开始整节点中的属性的增删改查

/day02/src/book.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?><书架>
    <书 id="1" name="Java">
        <书名>Java就业培训教程</书名>
        <作者>黎活明</作者>
        <售价>39.00元</售价>
    </>
    <>
        <书名>JavaScript网页开发</书名>
        <作者>张孝祥</作者>
        <售价>28.00元</售价>
    </>
</书架>

 

 /day02/src/cn/itcast/xml/Demo4.java

package cn.itcast.xml;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

public class Demo4 {

    public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException, TransformerException {
        //创建一个DOM解析工程
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //调用工程对象的newDocumentBuider()方法得到DOM解析器
        DocumentBuilder parser = factory.newDocumentBuilder();
        //通过DOM解析器解析XML,可以得到一个文档对象模型
        File f = new File("src/book.xml");
        Document document = parser.parse(f);        //这里不要倒错包,dom编程是w3c组织提供的,所以这里必须导入org.w3c.dom.Document
        updateAttr(document);
    }
    //为某个节点添加一个属性,这里我们为book.xml的第一本书添加一个属性id=1
    public static void addAttr(Document document) throws TransformerException{
    //首先我们要将属性创建出来
        Attr attribute = document.createAttribute("id");
        attribute.setValue("1");
        //将需要添加属性的节点找到
        Node books = document.getElementsByTagName("书").item(0);
        //开始为book这个节点添加属性,这里我们发现在Node中无法找到添加属性的方法,我们只有将Node转换成Element
        //Element中有添加属性的方法
        Element book = (Element) books;
        book.setAttributeNode(attribute);
        
        //其实上面可以不用先创建出属性,这里我们可以直接为某个节点添加属性和属性值
        book.setAttribute("name", "JavaBook");
        
        //将修改后的document写入到xml文件中去
        //先得到一个转换工厂类
        TransformerFactory factory = TransformerFactory.newInstance();
        //得到一个转换器
        Transformer transformer =factory.newTransformer();
        //开始将document转换到xml文件中去
        //这里要注意,我们用的Source资源是DOMSource,我们用的目标结果是StringResult
        transformer.transform(new DOMSource(document), new StreamResult(new File("src/book.xml")));
        System.out.println("添加属性成功");
        
    }
    //删除某个节点,这里我们删除第一本书中的name属性
    public static void deleteAttr(Document document) throws TransformerException{
        //删除某个节点的属性,我们就必须先找到这个节点
        Node books = document.getElementsByTagName("书").item(0);
        //将这个节点转换成Element,便于用Element中的方法删除属性
        Element book = (Element) books;
        //开始删除书这个节点中的name属性
        book.removeAttribute("name");
        //将修改后的document写入到xml文件中去
        //先得到一个转换工厂类
        TransformerFactory factory = TransformerFactory.newInstance();
        //得到一个转换器
        Transformer transformer =factory.newTransformer();
        //开始将document转换到xml文件中去
        //这里要注意,我们用的Source资源是DOMSource,我们用的目标结果是StringResult
        transformer.transform(new DOMSource(document), new StreamResult(new File("src/book.xml")));
        System.out.println("删除属性成功");
    }
    //修改某个节点属性的值,这里我们将name的值修改为Java, <书 id="1" name="JavaBook">
    //这里同事也演示了查找某个属性,所以查找的方法我们不做了
    public static void updateAttr(Document document) throws TransformerException{
        //首先获取到那个节点
        Node books = document.getElementsByTagName("书").item(0);
        //将这个节点转换成Element,便于用Element中的方法删除属性
        Element book = (Element) books;
        //获取到name那个属性
        Attr name = book.getAttributeNode("name");
        //将属性的值修改
        name.setValue("Java");
        //将修改后的document写入到xml文件中去
        //先得到一个转换工厂类
        TransformerFactory factory = TransformerFactory.newInstance();
        //得到一个转换器
        Transformer transformer =factory.newTransformer();
        //开始将document转换到xml文件中去
        //这里要注意,我们用的Source资源是DOMSource,我们用的目标结果是StringResult
        transformer.transform(new DOMSource(document), new StreamResult(new File("src/book.xml")));
        System.out.println("修改属性成功");
    }
}

 

 下面我们来遍历所有的节点

这里遍历节点要通过递归的方法将所有的节点打印出来

 /day02/src/book.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<书架>
    <书 id="1" name="Java">
        <书名>Java就业培训教程</书名>
        <作者>黎活明</作者>
        <售价>39.00元</售价>
    </>
    <>
        <书名>JavaScript网页开发</书名>
        <作者>张孝祥</作者>
        <售价>28.00元</售价>
    </>
</书架>

 

 /day02/src/cn/itcast/xml/Demo5.java

package cn.itcast.xml;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class Demo5 {

    public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException {
        //创建一个DOM解析工程
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //调用工程对象的newDocumentBuider()方法得到DOM解析器
        DocumentBuilder parser = factory.newDocumentBuilder();
        //通过DOM解析器解析XML,可以得到一个文档对象模型
        File f = new File("src/book.xml");
        Document document = parser.parse(f);        //这里不要倒错包,dom编程是w3c组织提供的,所以这里必须导入org.w3c.dom.Document
        findRootNode(document);
    }
    public static void findRootNode(Document document){
        //找到跟节点
        Node root = document.getElementsByTagName("书架").item(0);
        listNode(root);
    }
    public static void listNode(Node node){
        //获取到节点的名称
        System.out.println(node.getNodeName());
        //获取到节点的属性,由于节点和属性是同级关系,不是父子关系,所以这里要单独取属性
        NamedNodeMap map = node.getAttributes();
        //这里要注意将map!=null放在x<map.getLength()之前
        for(int x=0;map!=null&&x<map.getLength();x++){
            Attr attr = (Attr) map.item(x);
            System.out.println(attr.getName()+"="+attr.getValue());
        }
        //获取到节点所有的子节点
        NodeList list = node.getChildNodes();
        //循环出所有子节点
        for(int x=0;x<list.getLength() && list!=null;x++){
            Node childNode = list.item(x);
            listNode(childNode);
        }
    }
    
}

 

————————————————————————————————————————————————————————————————————

 06-xml编程案例

 等一段时间在做

 

posted @ 2013-09-13 15:15  ysfox  阅读(155)  评论(0)    收藏  举报