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

来源:互联网 发布:数据库round down函数 编辑:程序博客网 时间:2024/06/04 18:59

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 PRODUCTNAME CDATA #IMPLIEDCATEGORY (HandTool|Table|Shop-Professional) "HandTool"PARTNUM CDATA #IMPLIEDPLANT (Pittsburgh|Milwaukee|Chicago) "Chicago"INVENTORY (InStock|Backordered|Discontinued) "InStock"><!ELEMENT SPECIFICATIONS (#PCDATA)><!ATTLIST SPECIFICATIONSWEIGHT CDATA #IMPLIEDPOWER CDATA #IMPLIED><!ELEMENT OPTIONS (#PCDATA)><!ATTLIST OPTIONSFINISH (Metal|Polished|Matte) "Matte" ADAPTER (Included|Optional|NotApplicable) "Included"CASE (HardShell|Soft|NotApplicable) "HardShell"><!ELEMENT PRICE (#PCDATA)><!ATTLIST PRICEMSRP CDATA #IMPLIEDWHOLESALE CDATA #IMPLIEDSTREET CDATA #IMPLIEDSHIPPING 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 {@Testpublic 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文档中的所有标签@Testpublic 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文档中的标签属性的值@Testpublic 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 {@Testpublic 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文档中的所有标签@Testpublic 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文档中的标签属性的值@Testpublic 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</售价>@Testpublic 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</售价>@Testpublic 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"属性@Testpublic 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")));}@Testpublic 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文档@Testpublic 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")));}@Testpublic 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案例(考生成绩管理系统)


当要把异常当作一个返回值的时候,使用编译时异常,而其他情况使用运行时异常。

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 {@Testpublic 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);}@Testpublic void testFind(){StudentDao dao = new StudentDao();dao.find("121");}@Testpublic 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;//当前解析到的是第几个@Overridepublic void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {currentTag = qName;if(currentTag.equals("作者")){currentNumber++;}}@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {currentTag = null;}@Overridepublic 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;@Overridepublic void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {currentTag = qName;if("书".equals(currentTag)){book = new Book();}}@Overridepublic 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);}}@Overridepublic 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网页开发</书名>@Testpublic 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网页开发</书名>@Testpublic 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元</售价>@Testpublic 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 fileXMLWriter 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网页开发</书名>@Testpublic 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网页开发</书名>@Testpublic 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元</售价>@Testpublic 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-8writer.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网页开发</书名>@Testpublic 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网页开发</书名>@Testpublic 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元</售价>@Testpublic 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-8writer.close();}// 在第一本指定位置上添加一个新的售价: <售价>209元</售价> 更改list集合的顺序@Testpublic 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();}//删除上面添加的售价节点@Testpublic 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();}@Testpublic 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();}}}