黑马程序员 方立勋JavaWEB视频 第2、3天 xml笔记

时间:2023-02-18 12:07:43

01-xml语言和作用

XML:Extensible Markup Language,可扩展标记语言。
XML技术是W3C组织发布的,目前推荐遵循的是W3C组织于2000年发布的XML1.0规范。
XML语言出现的根本目标在于描述上图那种,在现实生活中经常出现的有关系的数据。
在XML语言中,它允许用户自定义标签。一个标签用于描述一段数据;一个标签可分为开始标签和结束标签,在开始标签和结束标签之间,又可以使用其他标签描述其他数据,以此来实现数据关系的描述。

<?xml version="1.0" encoding="UTF-8"?>

<中国>
<北京>
<海淀></海淀>
<丰台></丰台>
</北京>
<湖南>
<长沙></长沙>
<岳阳></岳阳>
</湖南>
<湖北>
<武汉></武汉>
<荆州></荆州>
</湖北>
</中国>


XML技术除用于保存有关系的数据之外,它还经常用作软件配置文件,以描述程序模块之间的关系。
在一个软件系统中,为提高系统的灵活性,它所启动的模块通常由其配置文件决定。
--例如一个软件在启动时,它需要启动A、B两个模块,而A、B这两个模块在启动时,又分别需要A1、A2和B1、B2模块的支持,为了准确描述这种关系,此时使用XML文件最为合适不过。

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

-文档声明
在编写XML文档时,需要先使用文档声明,声明XML文档的类型。
最简单的声明语法:
<?xml version="1.0" ?>
用encoding属性说明文档的字符编码:
<?xml version="1.0" encoding="GB2312" ?>
用standalone属性说明文档是否独立:
<?xml version="1.0" encoding="GB2312" standalone="yes" ?>
没有文档声明的文档成为格式不良好的XML文档
常见错误:
在记事本中以<?xml version="1.0" encoding="UTF-8" ?>来声明的xml文档,默认用ANSI编码保存在硬盘上,而用浏览器打开的时候是用文档声明中的UTF-8编码来解码的,所以出现乱码。可以在保存文档的时候以UTF-8编码来保存,那样在用浏览器打开的时候就不是乱码了。
而用eclipse和myeclipse来编写xml文档时,修改encoding时,这些IDE都会随之改变成对应的编码方式。
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>,standalone如果为"no",表示这个xml文件不是独立的,需要其他文档关联实现,但是很多浏览器都没有对应的解释器,无法识别。

-标签
xml元素指xml文件中出现的标签,一个标签分为开始标签和结束标签,一个标签有如下几种书写形式,例如:
    包含标签体:<a>www.itcast.cn</a>
    不含标签体的:<a></a>,简写为:<a/>
一个标签中也可以嵌套若干子标签。但所有标签必须合理的嵌套,却对不允许交叉嵌套,例如:
    <a>welcome to <b>www.it315.org</a></b>
格式良好的xml文档必须有且仅有一个根标签,其他标签都是这个根标签的子孙标签。

对于xml标签中出现的所有空格和换行,xml解析程序都会当做标签内容进行处理。例如:下面两段内容的意义是不一样的。
第一段:
<网址>www.itcast.cn</网址>

第二段:
<网址>
   www.itcast.cn
</网址>
由于在xml中,空格和换行都作为原始内容被处理,所以,在编写xml文件时,使用换行和缩进等方式来让原文件中的内容清晰可读的“良好”书写习惯可能要*改变。

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

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

-注释
xml文件中的注释采用:"<!--注释-->"格式。
注意:
    xml声明之前不能有注释
    注释不能嵌套,例如:
    <!--大段注释
    ……
      <!---局部注释->
    ……
    -->

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

转义字符
对于一些单个字符,若想显示其原始样式,也可以使用转义的形式予以处理。
特殊字符 替代符号
    &       &amp;
    <       &lt;
    >       &gt;
    "       &quot;
    .       &apos;

CDATA和转义的区别:
给人看原始样式用转义,给程序原始样式用CDATA区。

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

放在同一目录下的xml和css文件,可以通过浏览器显示文字样式。
xml文档:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type="text/css" href="config1.css"?>
<soft>
<a>
<a1 id="a1">中国</a1>
<a2 id="a2">美国</a2>
</a>
<b>
<b1 id="b1">日本</b1>
<b2 id="b2">英国</b2>
</b>
</soft>


css文档:

#a1{
font-size:300px;
color:red;
}
#a2{
font-size:100px;
color:green;
}
#b1{
font-size:20px;
}
#b2{
font-size:200px;
color:blue;
}


 

03-XmlDTD约束和DTD校验
XML约束概述
什么是XML约束
在XML技术里,可以编写一个文档来约束一个XML文档的书写规范,这称之为XML约束。
为什么需要XML约束
常用的约束技术:
XML DTD
XML Schema

DTD约束快速入门
DTD(Document Type Definition),全称为文档类型定义。
文件清单:

book.xml

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


book.dtd

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


 

DTD文件应使用UTF-8或Unicode

PCDATA(parse character data)可解析的字符数据

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


 

以上在ie中可以正确显示

Tip:编程校验XML文档正确性
IE5以上浏览器内置了XML解析工具:Microsort.XMLDOM,开发人员可以编写javascript代码,利用这个解析工具装载xml文件,并对xml文件进行dtd验证。
创建xml文档解析器对象
var xmldoc = new ActiveXObject("Microsoft.XMLDOM");
开启xml校验
xmldoc.validateOnParse="true";
装载文档
xmldoc.load("book.xml");
获取错误信息
xmldoc.parseError.reason;
xmldoc.parseError.line
但是如今开发不适用以上方法,使用myeclipse来校验
实际开发的时候不需要写dtd,而写框架人员需要写dtd,要求不高,要会读。

04-XMLDTD语法详解和分析struts的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">。

--当引用的文件是一个公共的文件时,采用如下方式:
<!DOCTYPE 文档根结点 PUBLIC "DTD名称" "DTD文件的URL">
例如:<!DOCTYPE web-app PUBLIC "-//Sun Microsystems.lnc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2.3.dtd">

DTD约束语法细节
元素定义
属性定义
实体定义

--元素定义1:
在DTD文档中使用ELEMENT声明一个XML元素,语法格式如下所示:
<!ELEMENT 元素名称 元素类型>
元素类型可以是元素内容、或类型
    如为元素内容:则需要使用()括起来,如
        <!ELEMENT 书架(书名,作者,售价)>
 <!ELEMENT 书名(#PCDATA)>
    如为元素类型,则直接书写,DTD规范定义了如下几种类型:
        EMPTY:用于定义空元素,例如<br/> <hr/>
 ANY:表示元素内容为任意类型。
  元素定义2:
元素内容中可以使用如下方式,描述内容的组成关系
    用逗号分隔,表示内容的出现顺序必须与声明时一致。
    <!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
  颜色 CDATA #IMPLIED
>
对应XML文件:
<商品 类别="服装" 颜色="黄色">...</商品>
<商品 类别="服装">...</商品>

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

举例:
<!ATTLIST 页面作者
  姓名 CDATA #IMPLIED
  年龄 CDATA #IMPLIED
  联系信息 CDATA #REQUIRED
  网站职务 CDATA #FIXED "页面作者"
  个人爱好 CDATA "上网"
>

<页面作者 联系信息="aaaa">
其中有三个属性,联系信息为一个,还有一个FIXED固定属性和一个默认属性。

常用属性值类型
CDATA:表示属性值为普通文本字符串。
ENUMERATED
ID
ENTITY(实体)

ENUMERATED
属性的类型可以是一组取值的列表,在XML文件中设置的属性值只能是这个列表中的某个值(枚举)

<?xml version="1.0" encoding="GB2312" standalone="yes" ?>
<!DOCTYPE 购物篮 [
<!ELEMENT 肉 EMPTY>
<!ATTLIST 肉 品种(鸡肉|牛肉|猪肉|鱼肉)"鸡肉">
]>
<购物篮>
<肉 品种="鱼肉"/>
<肉 品种="牛肉"/>
<肉/>
</购物篮>


ID
表示属性的设置值为一个唯一值,同一个xml文档中不能重复出现,id最好不要用数字开头。
ID属性的值只能由字符,下划线开始,不能出现空白字符。

<?xml version="1.0" encoding="GB2312" ?>
<!DOCTYPE 联系人列表 [
<!ELEMENT 联系人列表 ANY>
<!ELEMENT 联系人(姓名,EMAIL)>
<!ELEMENT 姓名(#PCDATA)>
<!ELEMENT EMAIL(#PCDATA)>
<!ATTLIST 联系人 编号 ID #REQUIRED>
]>

<联系人列表>
<联系人 编号="1">
<姓名>张三</姓名>
<EMAIL>zhang@it315.org</EMAIL>
</联系人>
<联系人 编号="2">
<姓名>李四</姓名>
<EMAIL>li@it315.org</EMAIL>
</联系人>
</联系人列表>


 

实体定义
使用用于为一段内容创建一个别名,以后在XML文档中就可以使用别名引用这段内容了。
在DTD定义中,一条<!ENTITY...>语句用于定义一个实体。
实体可分为两种类型:引用实体和参数实体。

引用实体
引用实体主要在XML文档中被应用
语法格式:
    <!ENTITY 实体名称 "实体内容">:直接转变成实体内容
引用方式:
  &实体名称:
举例:
  <!ENTITY copyright "I am a programmer">
  ......
  &copyright;

参数实体
参数实体被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;>
<!ATTLIST item %common.attributes>

struts里action标签里面什么属性是必须设置的:path(查看源文档)

05-DTD案例
DTD代码是W3C SCHOOL中的案例。

<?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>aaaa</SPECIFICATIONS>
<OPTIONS>aaaa</OPTIONS>
<PRICE>aaaa</PRICE><!-- DTD中price不能精确地限定为数字,所以正在被schema取代 -->
<NOTES>aaaa</NOTES>
</PRODUCT>
</CATALOG>


 

06-xml解析概述和DOM&SAX解析原理
XML编程(CRUD)
create read update delete

XML解析方式分为两种:dom和sax
dom:(Document Object Model,即文档对象模型)是W3C组织推荐的解析XML的一种方式。
sax:(Simple API for XML)不是官方标准,但它是XML社区事实上的标准,几乎所有的XML解析器都支持它。

XML解析开发包
Jaxp(sun)、Jdom、dom4j

dom方式:
优点:增删改查容易;
缺点:容易导致内存溢出,不能用于大文件。

sax方式:
从上往下读,读一行处理一行。
优点:内存消耗小。
缺点:不适合做增删改查。

Dom和sax解析方法的区别:
1.dom解析的优点是对文档crud比较方便,缺点是占用内存比较大。
2.sax解析的优点是占用内存少,解析速度快,缺点是只适合做文档的读取,不适合做文档的crud。

07-调整JVM内存大小
假设拿到的xml文档100兆
-Xmx200m

08-xml解析技术概述和使用Jaxp对xml文档进行dom解析
Jaxp(sun)、Jdom、dom4j
效率依次提高
JAXP
JAXP开发包是J2SE的一部分,它由javax.xml、org.w3c.dom、org.xml.sax包及其子包组成.
在javax.xml.parsers包中,定义了几个工厂类,程序员调用这些工厂类,可以得到xml文档的DOM或SAX的解析器,从而实现对xml文档的解析。
javax.xml.parsers包中的DocumentBuilderFactory用于创建DOM模式的解析器对象,DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供一个newInstance方法,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。

package cn.itcast.xml;

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

import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Demo3 {
@Test
public void read1() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");

//读取xml文档
NodeList list = document.getElementsByTagName("书名");
Node node = list.item(1);

String content = node.getTextContent();
System.out.println(content);
}

//得到xml文档中的所有标签
@Test
public void read2() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");

//得到根结点
Node root = document.getElementsByTagName("书架").item(0);
list(root);
}

//得到xml文档中的标签属性的值
@Test
public void read3() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");

Element bookname = (Element) document.getElementsByTagName("书名").item(0);
String value = bookname.getAttribute("name");
System.out.println(value);
}

private void list(Node node){
if(node instanceof Element){
System.out.println(node.getNodeName());
}
NodeList list = node.getChildNodes();
for(int i=0;i<list.getLength();i++){
Node child = list.item(i);
list(child);
}
}

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


09-使用JAXP对XML文档进行DOM解析
更新XML文档
javax.xml.transform包中的Transformer类用于把代表XML文件的Document对象转换为某种格式后进行输出,例如把xml文件应用样式表后转成一个html文档。利用这个对象,当然也可以把Document对象又重新写入到一个XML文件中。
Transformer类通过transform方法完成转换操作,该方法接收一个源和一个目的地。我们可以通过:
javax.xml.transform.dom.DOMSource类来关联要转换的document对象。
用javax.xml.transform.stream.StreamResult对象来表示数据的目的地。
Transformer对象通过TransformerFactory获得。

package cn.itcast.xml;

import java.io.FileOutputStream;

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

import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Demo3 {
@Test
public void read1() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");

//读取xml文档
NodeList list = document.getElementsByTagName("书名");
Node node = list.item(1);

String content = node.getTextContent();
System.out.println(content);
}

//得到xml文档中的所有标签
@Test
public void read2() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");

//得到根结点
Node root = document.getElementsByTagName("书架").item(0);
list(root);
}

//得到xml文档中的标签属性的值
@Test
public void read3() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");

Element bookname = (Element) document.getElementsByTagName("书名").item(0);
String value = bookname.getAttribute("name");
System.out.println(value);
}

//向xml文档中添加节点:<售价>59.00</售价>
@Test
public void add() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");

Element price = document.createElement("售价");
price.setTextContent("59.00元");

//把创建的节点挂到第一本书上
Element book = (Element) document.getElementsByTagName("书").item(0);
book.appendChild(price);

//把更新后的内存写回到xml文档
TransformerFactory tffactory = TransformerFactory.newInstance();
Transformer tf = tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));

}

//向xml文档中指定位置上添加节点:<售价>59.00</售价>
@Test
public void add2() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");

Element price = document.createElement("售价");
price.setTextContent("59.00元");

//得到参考节点
Element refNode = (Element) document.getElementsByTagName("售价").item(0);

Element book = (Element) document.getElementsByTagName("书").item(0);

book.insertBefore(price, refNode);

//把更新后的内存写回到xml文档
TransformerFactory tffactory = TransformerFactory.newInstance();
Transformer tf = tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));

}

//向xml文档节点上添加属性: <书名 name="xxxx">Java就业培训教程</书名>上添加name="xxx"属性
@Test
public void addAttr() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");

Element bookname = (Element) document.getElementsByTagName("书名").item(0);
bookname.setAttribute("name", "xxxxx");

//把更新后的内存写回到xml文档
TransformerFactory tffactory = TransformerFactory.newInstance();
Transformer tf = tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));

}

@Test
public void delete1() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");

//得到要删除的节点
Element e = (Element) document.getElementsByTagName("售价").item(0);

//得到要删除的结点的爸爸
Element book = (Element) document.getElementsByTagName("书").item(0);

//爸爸再删崽
book.removeChild(e);

//把更新后的内存写回到xml文档
TransformerFactory tffactory = TransformerFactory.newInstance();
Transformer tf = tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));
}

//删除整个xml文档
@Test
public void delete2() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");

//得到要删除的节点
Element e = (Element) document.getElementsByTagName("售价").item(0);
e.getParentNode().getParentNode().getParentNode().removeChild(e.getParentNode().getParentNode());

//把更新后的内存写回到xml文档
TransformerFactory tffactory = TransformerFactory.newInstance();
Transformer tf = tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));
}

@Test
public void update() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");

Element e = (Element) document.getElementsByTagName("售价").item(0);
e.setTextContent("109元");

//把更新后的内存写回到xml文档
TransformerFactory tffactory = TransformerFactory.newInstance();
Transformer tf = tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));
}

private void list(Node node){
if(node instanceof Element){
System.out.println(node.getNodeName());
}
NodeList list = node.getChildNodes();
for(int i=0;i<list.getLength();i++){
Node child = list.item(i);
list(child);
}
}

}


 

<?xml version="1.0" encoding="UTF-8" standalone="no"?><书架>
<书>
<书名 name="xxxxx">Java就业培训教程</书名>
<作者>张孝祥</作者>

<售价>109元</售价>
</书>
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00</售价>
</书>
</书架>


 

10-用xml作为持久化设备实现考生成绩管理系统
DOM方式解析XML文件
DOM解析编程
-遍历所有节点
-查找某一个节点
-删除结点
-更新结点
-添加节点
DOM编程练习

11-xml案例(考生成绩管理系统)

黑马程序员 方立勋JavaWEB视频 第2、3天 xml笔记
当要把异常当作一个返回值的时候,使用编译时异常,而其他情况使用运行时异常。

exam.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?><exam>
<student examid="222" idcard="111">
<name>张三</name>
<location>沈阳</location>
<grade>89</grade>
</student>

<student examid="444" idcard="333">
<name>李四</name>
<location>大连</location>
<grade>97</grade>
</student>
</exam>


Student.java

package cn.itcast.domain;

public class Student {
public String getIdcard() {
return idcard;
}
public void setIdcard(String idcard) {
this.idcard = idcard;
}
public String getExamid() {
return examid;
}
public void setExamid(String examid) {
this.examid = examid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public double getGrade() {
return grade;
}
public void setGrade(double grade) {
this.grade = grade;
}
private String idcard;
private String examid;
private String name;
private String location;
private double grade;
}


StudentDao.java

package cn.itcast.dao;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import cn.itcast.domain.Student;
import cn.itcast.exception.StudentNotExistException;
import cn.itcast.utils.XmlUtils;

public class StudentDao {
public void add(Student s){
try {
Document document = XmlUtils.getDocument();

//创建出封装学生信息的标签
Element student_tag = document.createElement("student");
student_tag.setAttribute("idcard", s.getIdcard());
student_tag.setAttribute("examid", s.getExamid());

//创建用于封装学生姓名,所在地和成绩的标签
Element name = document.createElement("name");
Element location = document.createElement("location");
Element grade = document.createElement("grade");

name.setTextContent(s.getName());
location.setTextContent(s.getLocation());
grade.setTextContent(s.getGrade()+"");

student_tag.appendChild(name);
student_tag.appendChild(location);
student_tag.appendChild(grade);

//把封装了信息学生标签,挂到文档上
document.getElementsByTagName("exam").item(0).appendChild(student_tag);

//更新内容
XmlUtils.write2Xml(document);
} catch (Exception e) {
throw new RuntimeException(e);
//unchecked exception(运行时异常)
} //checked exception(编译时异常)
}
public Student find(String examid){

try {
Document document = XmlUtils.getDocument();
NodeList list = document.getElementsByTagName("student");
for(int i=0;i<list.getLength();i++){
Element student_tag = (Element) list.item(i);
if(student_tag.getAttribute("examid").equals(examid)){
//找到与examid相匹配的学生,new出一个student对象封装这个学生的信息返回
Student s = new Student();
s.setExamid(examid);
s.setIdcard(student_tag.getAttribute("idcard"));
s.setName(student_tag.getElementsByTagName("name").item(0).getTextContent());
s.setLocation(student_tag.getElementsByTagName("grade").item(0).getTextContent());
s.setGrade(Double.parseDouble(student_tag.getElementsByTagName("grade").item(0).getTextContent()));
return s;
}
}
return null;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void delete(String name) throws StudentNotExistException{
try {
Document document = XmlUtils.getDocument();

NodeList list = document.getElementsByTagName("name");
for(int i=0;i<list.getLength();i++){
if(list.item(i).getTextContent().equals(name)){
list.item(i).getParentNode().getParentNode().removeChild(list.item(i).getParentNode());
XmlUtils.write2Xml(document);
return;
}
}
throw new StudentNotExistException(name + "不存在");
}catch(StudentNotExistException e){
throw e;
} catch (Exception e) {
throw new RuntimeException();
}

}
}


XmlUtils.java

package cn.itcast.utils;

import java.io.FileOutputStream;

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

import org.w3c.dom.Document;

/*
* 工具类方法要用static
*/
public class XmlUtils {

private static String filename = "src/exam.xml";

public static Document getDocument() throws Exception{

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(filename);
}
public static void write2Xml(Document document) throws Exception{

TransformerFactory factory = TransformerFactory.newInstance();
Transformer tf = factory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream(filename)));
}
}


StudentNotExistException.java

package cn.itcast.exception;

public class StudentNotExistException extends Exception {

public StudentNotExistException() {
// TODO Auto-generated constructor stub
}

public StudentNotExistException(String message) {
super(message);
// TODO Auto-generated constructor stub
}

public StudentNotExistException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}

public StudentNotExistException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}

public StudentNotExistException(String message, Throwable cause,
boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}

}


StudentDaoTest.java

package junit.test;

import org.junit.Test;

import cn.itcast.dao.StudentDao;
import cn.itcast.domain.Student;
import cn.itcast.exception.StudentNotExistException;

public class StudentDaoTest {
@Test
public void testAdd(){
StudentDao dao = new StudentDao();
Student s = new Student();
s.setExamid("121");
s.setGrade(89);
s.setIdcard("121");
s.setLocation("北京");
s.setName("aa");
dao.add(s);
}

@Test
public void testFind(){
StudentDao dao = new StudentDao();
dao.find("121");
}

@Test
public void testDelete() throws StudentNotExistException{
StudentDao dao = new StudentDao();
dao.delete("aa");
}
}


Main.java

package cn.itcast.UI;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import cn.itcast.dao.StudentDao;
import cn.itcast.domain.Student;
import cn.itcast.exception.StudentNotExistException;

public class Main {
public static void main(String[] args){
try {
System.out.println("添加学生(a) 删除学生(b) 查找学生(c)");
System.out.println("请输入操作类型:");

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String type = br.readLine();

if("a".equals(type)){
System.out.println("请输入学生姓名:");
String name = br.readLine();

System.out.println("请输入学生准考证号:");
String examid = br.readLine();

System.out.println("请输入学生身份证号:");
String idcard = br.readLine();

System.out.println("请输入学生所在地:");
String location = br.readLine();

System.out.println("请输入学生成绩:");
String grade = br.readLine();

Student s = new Student();
s.setExamid(examid);
s.setGrade(Double.parseDouble(grade));
s.setIdcard(idcard);
s.setLocation(location);
s.setName(name);

StudentDao dao = new StudentDao();
dao.add(s);

System.out.println("添加成功");
}else if ("b".equals(type)) {
System.out.println("请输入要删除的学生姓名:");
String name = br.readLine();

try {
StudentDao dao = new StudentDao();
dao.delete(name);
System.out.println("删除成功");
} catch (StudentNotExistException e) {
System.out.println("您要删除的用户不存在!!!");
}

}else if ("c".equals(type)) {

}else{
System.out.println("不支持您的操作!!");
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("对不起,我出错了");
}
}

}


 

12-sax解析原理与案例
SAX解析 jaxp dom
在使用DOM解析XML文档时,需要读取整个XML文档,在内存中构架代表整个DOM树的Document对象,从而再对XML文档进行操作。此种情况下,如果XML文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出。

SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会对文档进行操作。

SAX解析
SAX解析采用事件处理的方式解析XML文件,利用SAX解析XML文档,涉及两个部分:解析器和事件处理器:
    解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。

    解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在迪欧诺个用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。

    事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。
阅读ContentHandler API文档,常用方法:startElement、endElement、characters

book.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?><书架>
<书>
<书名 name="xxxxx">Java就业培训教程</书名>
<作者>张孝祥</作者>

<售价>109元</售价>
</书>
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00</售价>
</书>
</书架>


Demo2.java

package cn.itcast.sax;

import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class Demo2 {
/**
*sax 解析 xml文档
* @throws SAXException
* @throws ParserConfigurationException
* @throws IOException
*/
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException{
//1.创建解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();

//2.得到解析器
SAXParser sp = factory.newSAXParser();
//3.得到读取器
XMLReader reader = sp.getXMLReader();

//4.设置内容处理器
reader.setContentHandler(new TagValueHandler());
//5.读取xml文档内容
reader.parse("src/book.xml");
}
}

//获取指定标签的值
class TagValueHandler extends DefaultHandler{

private String currentTag; //记住当前解析到的是什么标签
private int needNumber = 2;//记住想获取第几个作者标签的值
private int currentNumber;//当前解析到的是第几个

@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentTag = qName;
if(currentTag.equals("作者")){
currentNumber++;
}
}

@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
currentTag = null;
}

@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if("作者".equals(currentTag) && currentNumber==needNumber){
System.out.println(new String(ch,start,length));
}
}
}


13-sax解析案例(javabean封装xml文档数据)
book.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?><书架>
<书>
<书名 name="xxxxx">Java就业培训教程</书名>
<作者>张孝祥</作者>

<售价>109元</售价>
</书>
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00</售价>
</书>
</书架>


Demo3.java

package cn.itcast.sax;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class Demo3 {
/**
*sax 解析 xml文档
* @throws SAXException
* @throws ParserConfigurationException
* @throws IOException
*/
@SuppressWarnings("unchecked")
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException{
//1.创建解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();

//2.得到解析器
SAXParser sp = factory.newSAXParser();
//3.得到读取器
XMLReader reader = sp.getXMLReader();

//4.设置内容处理器
BeanListHandler handle = new BeanListHandler();
reader.setContentHandler(handle);
//5.读取xml文档内容
reader.parse("src/book.xml");

List<Book> list = handle.getBooks();
System.out.println(list);
}
}

//把xml文档中的每一本数封装到一个book对象,并把多个book对象放在一个list集合中返回
class BeanListHandler extends DefaultHandler{

private List list = new ArrayList();
private String currentTag;
private Book book;
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentTag = qName;
if("书".equals(currentTag)){
book = new Book();
}
}

@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if("书名".equals(currentTag)){
String name = new String(ch,start,length);
book.setName(name);
}
if("作者".equals(currentTag)){
String author = new String(ch,start,length);
book.setAuthor(author);
}
if("售价".equals(currentTag)){
String price = new String(ch,start,length);
book.setPrice(price);
}
}

@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if(qName.equals("书")){
list.add(book);
book = null;
}
currentTag = null;
}

public List getBooks() {
return list;
}



}


 

14-断点跟踪sax解析案例,分析程序问题

15-dom4j解析xml文档
Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好地灵活性。

Dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用了Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j。

使用Dom4j开发,需下载dom4j相应的jar文件。
book.xml

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


demo1.java

package cn.itcast.dom4j;

import java.io.File;
import java.io.FileWriter;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;

public class Demo1 {
// 读取xml文档第二本书的:<书名>JavaScript网页开发</书名>
@Test
public void read() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));

Element root = document.getRootElement();
Element book = (Element) root.elements("书").get(1);
String value = book.element("书名").getText();
System.out.println(value);
}

// 读取xml文档第二本书的:<书名 name="xxxxx">JavaScript网页开发</书名>
@Test
public void readAttr() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));

Element root = document.getRootElement();
Element book = (Element) root.elements("书").get(1);
String value = book.element("书名").attributeValue("name");
System.out.println(value);
}

// 在第一本上添加一个新的售价: <售价>209元</售价>
@Test
public void add() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));

Element book = document.getRootElement().element("书");
book.addElement("售价").setText("$209");

// lets write to a file
XMLWriter writer = new XMLWriter(new FileWriter("src/book.xml"));
writer.write(document);
writer.close();
}
}


运行完出现乱码问题

<?xml version="1.0" encoding="UTF-8"?>
<���>
<��>
<���� name="xxxxx">Java��ҵ��ѵ�̳�</����>
<����>����</����>
<�ۼ�>109Ԫ</�ۼ�>
<�ۼ�>209Ԫ</�ۼ�></��>
<��>
<���� name="xxxxx">JavaScript��ҳ����</����>
<����>����</����>
<�ۼ�>28.00</�ۼ�>
</��>
</���>


16-dom4j保存数据的乱码问题
乱码不是dom4j的问题,而是sun公司io流的问题
FileWriter写的时候用的GB2312码表,不是UTF-8,但是FileWriter中没有可以指定编码方式的构造方法,所以不能使用。
book.xml

<?xml version="1.0" encoding="UTF-8"?>

<书架>
<书>
<书名 name="xxxxx">Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>109元</售价>
</书>
<书>
<书名 name="xxxxx">JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00</售价>
</书>
</书架>


Deom1.java

package cn.itcast.dom4j;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;

public class Demo1 {
// 读取xml文档第二本书的:<书名>JavaScript网页开发</书名>
@Test
public void read() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));

Element root = document.getRootElement();
Element book = (Element) root.elements("书").get(1);
String value = book.element("书名").getText();
System.out.println(value);
}

// 读取xml文档第二本书的:<书名 name="xxxxx">JavaScript网页开发</书名>
@Test
public void readAttr() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));

Element root = document.getRootElement();
Element book = (Element) root.elements("书").get(1);
String value = book.element("书名").attributeValue("name");
System.out.println(value);
}

// 在第一本上添加一个新的售价: <售价>209元</售价>
@Test
public void add() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));

Element book = document.getRootElement().element("书");
book.addElement("售价").setText("209元");

//格式化输入器
OutputFormat format = OutputFormat.createPrettyPrint();
//OutputFormat format = OutputFormat.createCompactFormat();
format.setEncoding("UTF-8");

// lets write to a file
//使用字节流,不要使用字符流
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);
//XMLWriter writer = new XMLWriter(new FileWriter("src/book.xml"),format);
writer.write(document);//UTF-8
writer.close();
}
}


17-dom4j解析xml文档(增删改查)
book.xml

<?xml version="1.0" encoding="UTF-8"?>

<书架>
<书>
<书名 name="xxxxx">Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>209元</售价>
</书>
<书>
<书名 name="xxxxx">JavaScript网页开发</书名>
<作者>活黎明</作者>
<售价>28.00</售价>
</书>
</书架>


Demo1.java

package cn.itcast.dom4j;

import java.io.File;
import java.io.FileOutputStream;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;
import org.xml.sax.DocumentHandler;

public class Demo1 {
// 读取xml文档第二本书的:<书名>JavaScript网页开发</书名>
@Test
public void read() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));

Element root = document.getRootElement();
Element book = (Element) root.elements("书").get(1);
String value = book.element("书名").getText();
System.out.println(value);
}

// 读取xml文档第二本书的:<书名 name="xxxxx">JavaScript网页开发</书名>
@Test
public void readAttr() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));

Element root = document.getRootElement();
Element book = (Element) root.elements("书").get(1);
String value = book.element("书名").attributeValue("name");
System.out.println(value);
}

// 在第一本上添加一个新的售价: <售价>209元</售价>
@Test
public void add() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));

Element book = document.getRootElement().element("书");
book.addElement("售价").setText("209元");

//格式化输入器
OutputFormat format = OutputFormat.createPrettyPrint();
//OutputFormat format = OutputFormat.createCompactFormat();
format.setEncoding("UTF-8");

// lets write to a file
//使用字节流,不要使用字符流
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);
//XMLWriter writer = new XMLWriter(new FileWriter("src/book.xml"),format);
writer.write(document);//UTF-8
writer.close();
}

// 在第一本指定位置上添加一个新的售价: <售价>209元</售价> 更改list集合的顺序
@Test
public void add2() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));

Element book = document.getRootElement().element("书");
List list = book.elements();//[书名,作者,售价]

Element price = DocumentHelper.createElement("售价");
price.setText("309");

list.add(2, price);

//格式化输入器
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");

XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);
writer.write(document);
writer.close();
}

//删除上面添加的售价节点
@Test
public void delete() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));

Element price = document.getRootElement().element("书").element("售价");
price.getParent().remove(price);

OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");

XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);
writer.write(document);
writer.close();
}

@Test
public void update() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));

Element book = (Element) document.getRootElement().elements("书").get(1);
book.element("作者").setText("活黎明");

OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");

XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);
writer.write(document);
writer.close();
}
}


18-XPath提取xml文档数据
users.xml

<?xml version="1.0" encoding="UTF-8"?>
<users>
<user id="1" username="aaa" password="123" email="aa@sina.com"/>
<user id="2" username="bbb" password="123" email="aa@sina.com"/>
</users>


Deom5.java

package cn.itcast.sax;

import java.io.File;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

public class Demo5 {

/**
* 查找users.xml文档是否有和用户相匹配的用户名和密码
* @throws DocumentException
*/
public static void main(String[] args) throws DocumentException {
String username = "aaa";
String password = "123";

//检测xml文档是否有匹配的用户名和密码
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/users.xml"));

Node node = document.selectSingleNode("//user[@username='"+username+"' and @password='"+password+"']");
if(node==null){
System.out.println("用户名或密码错误!");
}else{
System.out.println("登陆成功");
}
}

}


 

19-schema技术详解
XML Schema
XML Schema也是一种用于定义和描述XML文档结构与内容的模式语言,其出现是为了克服DTD的局限性
XML Schema VS DTD:
    XML Schema符合XML语法结构。
    DOM、SAX等XML API很容易解析出XML Schema文档中的内容。
    XML Schema对名称空间支持得非常好。
    XML Schema比XML DTD支持更多的数据类型,并支持用户自定义新的数据类型。
    XML Schema定义约束的能力非常强大,可以对XML实例文档作出细致的语义限制。
    XML Schema不能像DTD一样定义实体,比DTD更复杂,但Xml Schema现在已是w3c组织的标准,它正逐步取代DTD。

Schema约束快速入门
XML Schema文件自身就是一个XML文件,但它的扩展名通常为.xsd。
一个XML Schema文档通常称之为模式文档(约束文档),遵循这个文档书写的xml文件称之为实例文档。
和XML文件一样,一个XML Schema文档也必须有一个根结点,但这个根结点的名称为Schema。
编写了一个XML Schema约束文档后,通常需要把这个文件中声明的元素绑定到一个URI地址上,在XML Schema技术中有一个专业术语来描述这个过程,即把XML Schema文档声明的元素绑定到一个名称空间上,以后XML文件就可以通过这个URI(即名称空间)来告诉解析引擎,xml文档中编写的元素来自哪里,被谁约束。

book.xsd

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.itcast.cn" elementFormDefault="qualified">//unqualified只是绑定根结点,而qualified则是绑定所有的
<xs:element name='书架'>
<xs:complexType>
<xs:sequence maxOccurs='unbounded' >
<xs:element name='书' >
<xs:complexType>
<xs:sequence>
<xs:element name='书名' type='xs:string' />
<xs:element name='作者' type='xs:string' />
<xs:element name='售价' type='xs:string' />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>


book.xml

<?xml version="1.0" encoding="UTF-8"?>

<itcast:书架 xmlns:itcast="http://www.itcast.cn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.itcast.cn book.xsd">
<itcast:书>
<itcast:书名>JavaScript网页开发</itcast:书名>
<itcast:作者>张孝祥</itcast:作者>
<itcast:售价>28.00元</itcast:售价>
</itcast:书>
</itcast:书架>


 

名称空间的概念
在XML Schema中,每个约束模式文档都可以被赋以一个唯一的名称空间,名称空间用一个唯一的URI(Uniform Resource Identifier,统一资源标识符)表示。在Xml文件中书写标签时,可以通过名称空间声明(xmlns),来声明当前编写的标签来自哪个Schema约束文档。如:
<itcast:书架 xmlns:itcast="http://www.itcast.cn">
 <itcast:书>......</itcast:书>
<itcast:书架>
此处使用itcast来指向声明的名称,以便后面对名称空间的引用。
注意:名称空间的名字语法容易让人混淆,尽管以http://开始,那个URI并不指向一个包含模式定义的文件。事实上,这个URL:http://www.itcast.cn根本没有指向任何文件,只是一个分配的名字。

使用名称空间引入Schema
为了在一个XML文档中声明它所遵循的Schema文件的具体位置,通常需要在Xml文档中的根结点中使用schemaLocation属性来指定,例如:
<itcast:书架 xmlns:itcast="http://www.itcast.cn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.itcast.cn book.xsd">
schemaLocation此属性有两个值。第一个值是需要使用的命名空间。第二个值是供命名空间使用的XML schema的位置,两者之间用空格分隔。
注意,在使用schemaLocation属性时,也需要指定该属性来自哪里。

使用默认名称空间
基本格式:
xmlns="URI"
举例:

<书架 xmlns="http://www.it315.org/xmlbook/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.itcast.cn book.xsd">
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价 demo:币种="人民币">28.00元</售价>
</书>
</书架>


使用名称空间引入多个XML Schema文档
文件清单:xmlbook.xml

<?xml version="1.0" encoding="UTF-8"?>
<书架 xmlns="http://www.it315.org/xmlbook/schema" xmlns:demo="http://www.it315.org/demo/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.it315.org/xmlbook/schema http://www.it315.org/xmlbook.xsd http://www.it315.org/demo/schema http://www.it315/org/demo.xsd">
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价 demo:币种="人民币">28.00元</售价>
</书>
</书架>


不使用名称空间引入XML Schema文档
文件清单:xmlbook.xml

<?xml version="1.0" encoding="UTF-8"?>
<书架 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xmlbook.xsd">
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价 demo:币种="人民币">28.00元</售价>
</书>
</书架>


 

在XML Schema文档中声明名称空间
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.itcast.cn" elementFormDefault="qualified">
<xs:schema>

targetNamespace元素用于指定schema文档中声明的元素属于哪个名称空间。
elementFormDefault元素用于指定,该schema文档中声明的根元素及其所有子元素都属于targetNamespace所指定的名称空间。

20-schema语法详解和案例
shiporder.xml

<?xml version="1.0" encoding="UTF-8"?>

<shiporder xmlns="http://www.itcast.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.itcast.cn shiporder.xsd"
orderid="111">
<orderperson>xxx</orderperson>
<shipto>
<name>xxx</name>
<address>xxx</address>
<city>xxx</city>
<country>xxx</country>
</shipto>
<item>
<title>xxxx</title>
<note>xxxx</note>
<quantity>12</quantity>
<price>0.1</price>
</item>
</shiporder>


shiporder.xsd

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itcast.cn"
elementFormDefault="qualified">

<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="orderperson" type="xs:string" />
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="address" type="xs:string" />
<xs:element name="city" type="xs:string" />
<xs:element name="country" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string" />
<xs:element name="note" type="xs:string" minOccurs="0" />
<xs:element name="quantity" type="xs:positiveInteger" />
<xs:element name="price" type="xs:decimal" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:string" use="required" />
</xs:complexType>
</xs:element>

</xs:schema>


21一道打印M的面试题

package it.cast.demo;

public class Demo1 {
/*
3 7
2 4 6 8
1 5 9
平面图形(二维数组)
*/
public static void main(String[] args) {
int num = 13;

int height = num/4+1;
int width = num;

int[][] arr = new int[height][width];

int x = height-1;
int y = 0;

boolean order = false;
for(int i=1;i<=num;i++){
arr[x][y] = i;
y++;

if(order==false){
x--;
}
if(order==true){
x++;
}

if(x<0){
order = true;
x = x + 2;
}
if(x>height-1){
order = false;
x = x - 2;
}
}
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
if(arr[i][j]==0){
System.out.print(" ");
}else{
System.out.print(arr[i][j]);
}
}
System.out.println();
}
}
}

黑马程序员 方立勋JavaWEB视频 第2、3天 xml笔记黑马程序员 方立勋JavaWEB视频 第2、3天 xml笔记黑马程序员 方立勋JavaWEB视频 第2、3天 xml笔记黑马程序员 方立勋JavaWEB视频 第2、3天 xml笔记