DTD、Schema、Dom、Sax"/>
JavaEE开发——XML、DTD、Schema、Dom、Sax
XML
名称:可扩展标记语言,Extendsible Markup Language
用途:xml的出现就是描述一些有关系的数据,现在主要作为软件的配置文件以描述程序模块之间的关系
明确:我们学习的是w3c组织2000年发布的XML1.0规范
一. XML
1.文档声明
(1)如果没有此XML文档是一个格式不良好的文档,一个XML文档必须要有文档说明。文档说明是告诉处理引擎如何解析xml文档中的内容
(2)最简单的声明:<?xml version="1.0"?>
(3)用encoding属性说明文档的字符编码:<?xml version="1.0" encoding="utf-8"?>——指的是浏览器打开时使用的码表,如果有除ASCII码表以外码表字符时,必须要指定这个属性,否则XML文档无法被浏览器所打开
(4)用standalone属性说明文档是否独立:<?xml version="1.0" encoding="GB2312" standalone=“yes"?>——当这个文档是依赖于另外一个文档而存在的,这里属性值应该为"no"
2.元素——> 标签
(1)格式良好的xml文档有且仅有一个根标签
(2)标签体中的空格和换行都会作为原始内容被处理,所有有时不能够输入
(3)便签名区分大小写
3.属性
(1)属性名区分大小写
(2)属性所代表的信息也可以改为子元素(子标签)的形式来描述
4.注释
(1)格式与html注释相同,不过要注意文档声明钱不能有注释
5.CDATA区
特点:不会被xml解析引擎解析处理,而是作为原始内容直接输出表示
语法格式:<![CDATA[内容]]>
<?xml version="1.0" encoding="gbk"?>
<!--我是注释-->
<黑马><我 property="我是属性"><JavaSE>毕向东</JavaSE><JavaEE>方立勋</JavaEE></我><![CDATA[<前我><html_css>张鹏</html_css></前我>]]>
</黑马>
6.转义字符
(1)【&】——>&
(1)【>】——>>
(1)【<】——><
(1)【"】——>"
(1)【'】——>'
7.处理指令
用法:简称PI(processing instruction)处理指令用来指挥解析引擎如何解析xml文档内容——>说明文档就是一个处理指令
例如:<?xml-stylesheet type="text/css" href="css文件地址"?>——>告诉处理引擎用css文件装饰此XML文档
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type="text/css" href="config.css"?>
<body><head><![CDATA[<a1>现充</a1><a2>死宅</a2>]]></head><tbody><b1>技术宅</b1><b2>工业宅</b2></tbody>
</body>
二. DTD
说明:DTD(文档类型定义 Document Type Definition)
意义:用来约束XML文档的书写规范,有时相当于XML的帮助文档
1.三种引用方式
(1)在xml文档内部 <!DOCTYPE xml文档根节点 [DTD代码]>
(2)单独存在于本地系统 <!DOCTYPE xml文档根节点 SYSTEM ”文件位置“>
(3)存在于网络公共地址 <!DOCTYPE xml文档根节点 PUBLIC "DTD名称” “DTD文件位置(url)">
按照指定DTD书写规范的xml文档(如代码所示)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE 书架 SYSTEM "book.dtd">
<书架><书><书名>OTAKU信息</书名><作者>桂马</作者><售价>1000</售价></书><书><书名>达人</书名><作者>doing</作者><售价>10</售价></书>
</书架>
DTD规范文档(如代码所示)
<!ELEMENT 书架 (书+)>
<!ELEMENT 书 (书名,作者,售价)>
<!ELEMENT 书名 (#PCDATA)>
<!ELEMENT 作者 (#PCDATA)>
<!ELEMENT 售价 (#PCDATA)>
2.DTD语法
2.1 元素定义
(1)DTD中使用ELEMENT声明一个xml元素
(2)语法格式: <!ELEMENT 元素名称 元素类型>——(元素类型:可以是元素内容或元素类型)
(3)缺点:DTD无法对数据进行更精细的操作,比如约束数据只能输入 数字 就不能用DTD实现
2.1.1 元素内容
<1>. 元素内容可用【,】逗号来分割,表示内容出现顺序必须与声明时一致
<2>. 元素内容可用【|】或的符号来分割,表示任选其一,即多个中只能出现一个
<3>. 元素内容中可以使用【+】【*】【?】来表示元素的出现次数
【+】——>一次或多次 【?】——>零次或一次 【*】——>零次或多次 (可以使用【()】小括号形式进行次数批量设置)
注意:书写时需用小括号括起来
<!ELEMENT MYFILE ((TITLE*, AUTHOR?, EMAIL)* | COMMENT)>
<!--COMMENT和前边只能有添加一个,前边中TITLE可出现0次或多次,
AUTHOR可出现1次货多次,EMAIL必须出现1次。不过这三个元素放在一起可出现0次或者多次-->
2.1.2 元素类型
<1>. EMPTY:用于定义空元素,指标签内不能添加内容——> <书 />
<2>. ANY:表示元素内容为任意类型,指标签内容任意
注意:书写时不用小括号括起来,DTD定义的元素类型就这几种
2.2 属性定义
(1)DTD中通过ATTLIST约束XML文档属性
(2)语法格式:
<!ATTLIST 元素名属性名1 属性值类型 设置说明属性名2 属性值类型 设置说明......
>
2.2.1 属性值类型
<1>. CDATA:字符串
<2>. ENUMERATED:枚举——>(鸡肉 | 牛肉 | 猪肉 | 鱼肉)
<3>. ID:整个XML文档中属性值必须唯一(id值最好以字母开头,不要单单就写一个数字)
<4>. 参数实体:直接写实体名即可(实体中定义了属性名,ATTLIST中不要再写属性名)
<?xml version = "1.0" encoding="GB2312" standalone="yes"?>
<!DOCTYPE 购物篮 [<!ELEMENT 肉 EMPTY><!ATTLIST 肉 品种 ( 鸡肉 | 牛肉 | 猪肉 | 鱼肉 ) "鸡肉"><!--肉标签中品种属性值类型为这个枚举类型,并且默认值为 鸡肉-->
]>
<购物篮><肉 品种="鱼肉"/><!--鱼肉是枚举值其中一个--><肉 品种="牛肉"/><!--牛肉是枚举值其中一个--><肉/>
</购物篮><!--===============================================================================================--><?xml version = "1.0" encoding="GB2312" ?><!DOCTYPE 联系人列表[<!ELEMENT 联系人列表 ANY><!--联系人列表标签中可添加任何元素--><!ELEMENT 联系人(姓名,EMAIL)><!--联系人标签中只能是姓名和EMAIL标签--><!ELEMENT 姓名(#PCDATA)><!ELEMENT EMAIL(#PCDATA)><!ATTLIST 联系人 编号 ID #REQUIRED><!--联系人标签中编号属性值为ID类型,并且是必须填写的属性-->
]><联系人列表><联系人 编号="1"><!--添加了编号属性,不过属性最好为字母开头--><姓名>张三</姓名><EMAIL>zhang@it315</EMAIL></联系人><联系人 编号="2"><姓名>李四</姓名><EMAIL>li@it315</EMAIL></联系人>
</联系人列表>
2.2.2 设置说明
<1>. #REQUIRED:必须设置该属性
<2>. #IMPLIED:设置是否均可(可选的)
<3>. #FIXEED:该属性取值固定为一个值,在XML文档中不能为该属性设置其它值。但需要为该属性提供这个值。固定值跟在注释后边
<4>. 默认值:在XML文档中可以设置该值,也可以不设置,若没设置则使用默认值
<!ATTLIST 页面作者 姓名 CDATA #IMPLIED <!--可选的-->年龄 CDATA #IMPLIED 联系信息 CDATA #REQUIRED <!--必须的-->网站职务 CDATA #FIXED "页面作者" <!--固定值为"页面作者"-->个人爱好 CDATA "上网" <!--默认值-->
>
2.3.实体
意义:实体用于为一段内容创建一个别名,以后在XML文档中就可以使用别名引用这段内容了
规则:DTD中通过ENTITY来定义一个实体
2.3.1 引用实体: 应用给XML文档
<1>. 语法格式:<!ENTITY 实体名称 “实体内容”>
<2>. 引用方式:&实体名称;
2.3.2 参数实体: 应用给DTD文档
<1>. 语法格式:<!ENTITY % 实体名称 "实体内容" >
<2>. 引用方式:%实体名称
<!--引用实体,给XML文档引用-->
<!ENTITY copyright “I am a programmer"> ……©right;<!--参数实体,给DTD文档中-->
<!--举例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;>
3. DTD语法验证( 实例代码,看懂即可)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE CATALOG [<!ENTITY AUTHOR "John Doe">
<!ENTITY COMPANY "JD Power Tools, Inc.">
<!ENTITY EMAIL "jd@jd-tools"><!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 NAME="adaf" ><SPECIFICATIONS>SDFASD</SPECIFICATIONS><OPTIONS>DFAF</OPTIONS><PRICE>ASDFA</PRICE></PRODUCT>
</CATALOG>
三. Schema
(1)Schema本身是一个Xml,Dom、Sax能够解析Schema
(2)Schema相比DTD更复杂,但它已是w3c组织的标准,正逐步取代DTD
(3)Schema文件扩展名为 .xsd
(4)Schema文档通称模式文档,按照这个文档写的xml称为实例文档
1.引用方式
<简称:根节点 xmlns:定义简称="Schema中定义的名称空间(uri)"xmlns:xsi="http:www.w3/2001/XMLSchema-instance"xsi:schemaLocation="名称空间(前面的) Schema文档地址位置"><简称:标签名>第一份实例文档</简称:标签名><!--文档中需要约束的元素全部用定义的简称名修饰,不管是元素头还是尾-->
</简称:根节点>
xmlns:是系统识别的关键字,可以理解为一种变量类型
简称:就是名称空间的简写形式,一个引用,指向定义的名称空间
名称空间:通常名称空间是一个http地址,不过这个URI不指文件,可以看为一个值唯一的字符串标记
schemaLocation:其中定义了约束文档Schema的地址,这个关键字来自于xsi
xsi:定义的变量名,引用的是之后的名称空间,这个名称空间是个著名空间,会被Schema解析引擎所识别,会去找这个命名空间所对应的Schema文档
默认名称空间:(省略简称)
<根节点 xmlns="Schema中定义的名称空间(uri)"xmlns:xsi="http:www.w3/2001/XMLSchema-instance"xsi:schemaLocation="名称空间(前面的) Schema文档地址位置"><标签名>第一份实例文档</标签名><!--全部元素都是必须符合Schema约束的-->
</根节点>
引用多个Schema约束文档:
<根节点 xmlns="Schema中定义的名称空间(uri)"xmlns:demo="Schema中定义的名称空间(uri)"xmlns:xsi="http:www.w3/2001/XMLSchema-instance"xsi:schemaLocation="名称空间(前面的) Schema文档地址位置 名称空间(前面的) Schema文档地址位置"><标签名 demo:属性名="属性值">第一份实例文档</标签名><!--全部元素都是必须符合Schema约束的,demo修饰的符合另一个Schema约束-->
</根节点>
2.Schema语法
2.1 根元素<schema>定义
(1)根标签必须为Schema
(2)根标签定义实例:
<xs:schema xmlns:xs=""targetNamespace="自定义的名称空间"xmlns=""elementFormDefault="qualified">
<!--elementFormDefault的值可以为qualified和unqualified,前者为xsd中的全部元素绑定到名称空间中,-->
<!--后者只有根节点绑定到名称空间上-->
(3)完整的Xml与其绑定的Schema文档演示 <?xml version="1.0"?>
<!--Schema文档-->
<xs:schema xmlns:xs=""
targetNamespace=""
xmlns=""
elementFormDefault="qualified">
<xs:element name="note"> <xs:complexType> <xs:sequence> <xs:element name="to" type="xs:string"/> <xs:element name="from" type="xs:string"/> <xs:element name="heading" type="xs:string"/> <xs:element name="body" type="xs:string"/> </xs:sequence> </xs:complexType>
</xs:element>
</xs:schema> <!--===========================================================================-->
<?xml version="1.0"?>
<!--对应Xml文档-->
<note
xmlns=""
xmlns:xsi=""
xsi:schemaLocation=" note.xsd">
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
2.2 简单元素与属性
(1)简单元素语法:<xs:element name="xxx" type="yyy">
(2)简单属性语法:<xs:attribute name="xxx" type="yyy">
(2)元素或属性类型:(Text的数据类型,属性值类型)
- xs:string——字符串
- xs:decimal——小数
- xs:integer——整数
- xs:boolean——布尔值
- xs:date——日期
- xs:time——时间
(3)默认值和固定值
<1>.默认值:<xs:element name="color" type="xs:string" default="red"/>
<2>.固定值:<xs:element name="color" type="xs:string" fixed="red"/>
2.3 限定类型
限定 | 描述 |
---|---|
enumeration | 定义可接受值的一个列表 |
fractionDigits | 定义所允许的最大的小数位数。必须大于等于0。 |
length | 定义所允许的字符或者列表项目的精确数目。必须大于或等于0。 |
maxExclusive | 定义数值的上限。所允许的值必须小于此值。 |
maxLength | 定义所允许的字符或者列表项目的最大数目。必须大于或等于0。 |
minExclusive | 定义数值的下限。所允许的值必需大于此值。 |
minInclusiv | 定义数值的下限。所允许的值必需大于或等于此值。 |
minLength | 定义所允许的字符或者列表项目的最小数目。必须大于或等于0。 |
pattern | 定义可接受的字符的精确序列 |
totalDigits | 定义所允许的阿拉伯数字的精确位数。必须大于0。 |
whiteSpace | 定义空白字符(换行、回车、空格以及制表符)的处理方式。 |
(1)用法实例:
<1>.下面的例子定义了带有一个限定的名为 "age" 的元素。age 的值不能低于 0 或者高于 120:
<xs:element name="age">
<xs:simpleType><xs:restriction base="xs:integer"><xs:minInclusive value="0"/><xs:maxInclusive value="120"/></xs:restriction>
</xs:simpleType>
</xs:element>
<2>.下面的例子定义了带有一个限定的名为 "car" 的元素。可接受的值只有:Audi, Golf, BMW:
<xs:element name="car">
<xs:simpleType><xs:restriction base="xs:string"><xs:enumeration value="Audi"/><xs:enumeration value="Golf"/><xs:enumeration value="BMW"/></xs:restriction>
</xs:simpleType>
</xs:element>
<3>.类型可以定义名字,分配给多个使用者
<xs:element name="car" type="carType"/>
<xs:simpleType name="carType"><xs:restriction base="xs:string"><xs:enumeration value="Audi"/><xs:enumeration value="Golf"/><xs:enumeration value="BMW"/></xs:restriction>
</xs:simpleType>
<4>.下一个例子定义了带有一个限定的名为 "initials" 的元素。可接受的值是大写字母 A - Z 其中的三个:
<xs:element name="initials">
<xs:simpleType><xs:restriction base="xs:string"><xs:pattern value="[a-zA-Z][a-zA-Z][a-zA-Z]"/></xs:restriction>
</xs:simpleType>
</xs:element>
2.4 复杂类型与类型指示器
(1)复杂类型分为四种如下:(详细请查看文档)
- 空元素
- 包含其他元素的元素
- 仅包含文本的元素
- 包含元素和文本的元素
(2)类型指示器
<1>.Order指示器
- All——随机出现,无所谓
- Choice——要么有前一个,要么有后一个
- Sequence——必须是按照Schema文档中的前后排列顺序
<2>.Occurrence指示器
- maxOccurs——最多出现几次
- minOccurs——最少出现几次
(3)实例演示
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs=""
elementFormDefault="qualified"><xs:element name="persons"><xs:complexType><xs:sequence><xs:element name="person" maxOccurs="unbounded"><!--表示出现次数没有上限--><xs:complexType><!--复杂类型--><xs:sequence><xs:element name="full_name" type="xs:string"/><xs:element name="child_name" type="xs:string"minOccurs="0" maxOccurs="5"/></xs:sequence></xs:complexType></xs:element></xs:sequence></xs:complexType>
</xs:element></xs:schema>
2.5 Schema检验 (通过Schema能够写出Xml文档)
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs=""><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>
xml文档如下:
四. XML编程(CRUD)
目的:因为XML有获取关系数据的作用,如果你想获取这些数据,你必然会对其进行解析
1.解析方式
1.1 DOM解析
(1)解释:dom解析(Document Object Model)文档对象模型
(2)原理:解析引擎会转载整个Xml文档,在内存中建立关于文档中节点对象,并按照节点关系建立对象间的关系,形成一颗对象树
(3)使用:程序员要得到代表文档的Document对象,就可以遍历出所有节点。并且通过调用节点对象的方法,可以方便的实现对Xml文档的CURD
(4)优点:增删改方便
(5)缺点:因为需装在整个Xml文档,对计算机内存消耗巨大,文档过大的话可能会内存溢出,不适合处理大文档
1.2 Sax解析
(1)特点:边解析边处理,占用内存少,解析速度快
(2)缺点:不能对Xml文档进行CUD的操作
2.解析器
理解:解析器就是指工具,对Xml进行解析的是已经编程好的工具,里边封装了Dom与Sax两种解析方式,我们用的API就是其给外边提供的能够访问的接口
2.1 Crimson
了解:sun公司开发,最垃圾,Jdk1.4以前Java自己用的就是这个解析器。此解析器现在属于Apache
2.2 Xerces
了解:IBM公司开发,性能不错,Jdk1.4以后Sun公司不用自己的解析器了,反而用这个解析器解析Xml。此解析器现在属于Apache
2.3 Aelfredz
了解:dom4j组织开发,性能不错
3.开发包
理解:解析器的能够访问的接口
3.1 JAXP
了解:sun公司开发,用的是Xerces解析器,性能最差,不过要会用
3.2 Jdom
了解:Jdom组织开发,用的是Aelfredz解析器,性能适中(几乎不用)。Jdom组织分裂后生成了dom4j
3.3 dom4j
了解:dom4j组织开发,用的是Aelfredz解析器,性能最好,dom4j基本代替了Jdom,所有要会用
4.Jasp工具包具体使用
位置:JAXP开发包是JavaSE的一部分,javax.xml包、orc.w3c.dom包、org.xml.sax包以及其子包组成
使用:JAXP在Javax.xml.parse包中定义了一些工厂类,你只需调用工厂类中的方法既可得到对Xml进行解析dom对象或者Sax对象
4.1 Dom解析实现
重要:Document对象树中所有节点对象都是Node的子类对象,文档的根节点、子节点与内容【空格换行与标签内容】都是Element的子类对象
DocumentBuilderFactory抽象类
位置:javax.xml.parsers包
方法摘要 | |
---|---|
static DocumentBuilderFactory | newInstance() 获取 DocumentBuilderFactory 的新实例。(建立解析器工厂) |
abstract DocumentBuilder | newDocumentBuilder() 使用当前配置的参数创建一个新的 DocumentBuilder 实例。(生产出一个Dom解析器) |
DocumentBuilder类
位置:javax.xml.parsers包
方法摘要 | |
---|---|
Document | parse(File f) 将给定文件的内容解析为一个 XML 文档,并且返回一个新的 DOM Document 对象。(通过解析Xml文档返回对象树根节点Document对象,之后可用递归方法获取对象树中全部的节点) |
Node接口
方法摘要 | |
---|---|
String | getTextContent() 此属性返回此节点及其后代的文本内容。 |
void | setTextContent(String textContent) 此属性返回此节点及其后代的文本内容。 |
NodeList | getChildNodes() 包含此节点的所有子节点的 NodeList 。(获取全部子节点并存入NodeList容器中) |
Node | getFirstChild() 此节点的第一个子节点。 |
Node | getLastChild() 此节点的最后一个节点。 |
String | getNodeName() 此节点的名称,取决于其类型;参见上表。 |
Node | appendChild(Node newChild) 将节点 newChild 添加到此节点的子节点列表的末尾。(通过父节点来插入节点到末尾) |
Node | insertBefore(Node newChild,Node refChild) 在现有子节点 refChild 之前插入节点 newChild 。(通过父节点来插入节点到指定位置) |
Node | removeChild(Node oldChild) 从子节点列表中移除 oldChild 所指示的子节点,并将其返回。(通过父节点来删除指定子节点,并返回) |
Node | replaceChild(Node newChild,Node oldChild) 将子节点列表中的子节点 oldChild 替换为 newChild ,并返回 oldChild 节点。(通过父节点来修改子节点为指定节点) |
Node | getParentNode() 此节点的父节点。 |
Document接口
方法摘要 | |
---|---|
Element | getElementById(String elementId) 返回具有带给定值的 ID 属性的 Element 。 |
NodeList | getElementsByTagName(String tagname) 按文档顺序返回包含在文档中且具有给定标记名称的所有 Element 的 NodeList 。 |
Element | createElement(String tagName) 创建指定类型的元素。 |
Element接口
方法摘要 | |
---|---|
String | getAttribute(String name) 通过名称获得属性值。 |
void | setAttribute(String name,String value) 添加一个新属性。 |
NodeList | getElementsByTagName(String name) 以文档顺序返回具有给定标记名称的所有后代 Elements 的 NodeList 。 |
NodeList接口
方法摘要 | |
---|---|
int | getLength() 列表中的节点数。 |
Node | item(int index) 返回集合中的第 index 个项。 |
TransformerFactory抽象类
方法摘要 | |
---|---|
static TransformerFactory | newInstance() 获取 TransformerFactory 的新实例。(获取转换器工厂对象) |
abstract Transformer | newTransformer() 创建执行从 Source 到 Result 的复制的新 Transformer 。(获取解析器) |
Transformer类
重要:把内存中的对象树更新到Xml文档的功能可用该类实现。此类具有把某Document对象转换为某种格式进行输出。例如把Xml文件应用样式表转换为一个html文档
方法摘要 | |
---|---|
abstract void | transform(Source xmlSource,Result outputTarget) 将 XML Source 转换为 Result 。(把代表Source的内存对象更新到本地文件中) |
DomSource类
主要:此类是Source接口的子类
构造方法摘要 | |
---|---|
DOMSource(Node n) 创建带有 DOM 节点的新输入源。(传入节点对象构造Source) |
StreamResult类
主要:此类是Result接口的子类
构造方法摘要 | |
---|---|
StreamResult(File f) 从 File 构造 StreamResult。 | |
StreamResult(OutputStream outputStream) 从字节流构造 StreamResult。(传入输出流构造对象) |
代码实现
package cn.doing.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.Before;
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 ParseXml {private Document document;@Beforepublic void before()throws Exception{DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();//得到dom解析器DocumentBuilder builder = factory.newDocumentBuilder();System.out.println(builder);document = builder.parse("src/03.ParseXml/01.ParseOTAKU.xml");}//遍历Xml结点信息打印在控制台上@Testpublic void parse_01() {list(document);}//遍历文档节点的具体实现public void list(Node n){System.out.println(n.getNodeName());NodeList list = n.getChildNodes();for(int x=0; x<list.getLength(); x++){Node child = list.item(x);list(child);}}//获取xml文档中具体标签中的值 <a1>现充</a1>@Testpublic void parse_02(){Node node = document.getElementsByTagName("a1").item(0);System.out.println(node.getTextContent());}//获取xml文档标签中属性的值 <a1>现充</a1>@Testpublic void parse_03(){//结点包括很多,标签、文本、PI指令、属性这些,因为只有标签才具有属性值,如果需要获取属性值,只能强转为Element后才有这个功能。Element type = (Element) document.getElementsByTagName("a1").item(0);String value = type.getAttribute("type");System.out.println(value);}//插入结点在指令标签中@Testpublic void parse_04() throws Exception{//创建要挂的结点Element a3 = document.createElement("a1");a3.setTextContent("Java持续进步中!");a3.setAttribute("type", "程序员");//把创建的结点挂到head结点下Node node = document.getElementsByTagName("head").item(0);node.appendChild(a3);//使内存中更新的对象树加载到实体XML文件当中 TransformerFactory factory = TransformerFactory.newInstance();Transformer tran = factory.newTransformer();tran.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/03.ParseXml/01.ParseOTAKU.xml")));}//在指定位置插入结点@Testpublic void parse_05() throws Exception{//创建要挂的标签Element a4 = document.createElement("a4");a4.setTextContent("我的JAVA");a4.setAttribute("type", "我的");//获取要挂标签的节点与此节点中要挂子节点的位置Node head = document.getElementsByTagName("head").item(0);Node before = document.getElementsByTagName("a1").item(0);head.insertBefore(a4, before);//是内存中的更新的对象树加载到XML文件当中TransformerFactory factory = TransformerFactory.newInstance();Transformer tran = factory.newTransformer();tran.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/03.ParseXml/01.ParseOTAKU.xml")));}//删除指令结点@Testpublic void parse_06() throws Exception{//获取父节点与要删除的子节点Element father = (Element) document.getElementsByTagName("head").item(0);Node child= document.getElementsByTagName("a4").item(0);//简单方法为:child.getParentNode().removeChild(child);//通过父节点方法删除子节点//father.removeChild(child);//把内存中更新的对象树加载到XML文件当中TransformerFactory factory = TransformerFactory.newInstance();Transformer tran = factory.newTransformer();tran.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/03.ParseXml/01.ParseOTAKU.xml"))); }
}
4.2 Sax解析实现
SAXParserFactory抽象类
方法摘要 | |
---|---|
static SAXParserFactory | newInstance() 获取 SAXParserFactory 的一个新实例。(建立一个SAX解析器工厂) |
abstract SAXParser | newSAXParser() 使用当前配置的工厂参数创建 SAXParser 的一个新实例。(获取SAX解析器) |
SAXParser类
方法摘要 | |
---|---|
abstract XMLReader | getXMLReader() 返回由此类的实现封装的 XMLReader 。(获取XML读取器) |
void | parse(InputStream is,DefaultHandler dh) 使用指定的 DefaultHandler 将给定的InputStream 实例的内容解析为 XML。(方便的解析方法,内部封装了读取器) |
XMLReader类
位置:org.xml.sax包
方法摘要 | |
---|---|
void | setContentHandler(ContentHandler handler) 允许应用程序注册内容事件处理程序。(往解析器里面注册一个自定义的处理器) |
void | parse(InputSource input) 解析 XML 文档。 |
ContentHandler接口
方法摘要 | |
---|---|
void | startElement(String uri,String localName,String qName,Attributes atts) 接收元素开始的通知。(解析到一个开始标签时调用此方法,qName是指标签名,atts是存储标签中全部属性的集合) |
void | endElement(String uri,String localName,String qName) 接收元素结束的通知。(解析到一个结束标签时调用此方法,qName是指标签名) |
void | characters(char[] ch, int start, int length) 接收字符数据的通知。(解析到内容时调用此方法,会把解析到的数据存储到ch字符数组中,start数存储数据的开始位置,length是数据长度) |
DefaultHandler类
注意:此类是ContentHandler的子类,是一个适配器类,通常写处理器会继承此类
Attributes接口
方法摘要 | |
---|---|
int | getLength() 返回此列表中的属性个数。 |
String | getQName(int index) 通过索引查找属性的 XML 限定(前缀)名。 |
String | getValue(int index) 通过索引查找属性的值。 |
代码实现
功能:遍历xml文档所有节点
package First.doing.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.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;public class ListHandler {/*** @param args* @throws SAXException * @throws ParserConfigurationException * @throws IOException */public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {//1.获取解析器的工厂SAXParserFactory factory = SAXParserFactory.newInstance();//2.获取解析器SAXParser parser = factory.newSAXParser();//3.获取解析器的读取器XMLReader reader = parser.getXMLReader();//4.向读取器中传入处理器reader.setContentHandler(new DefaultHandler(){//读取到标签开始处调用@Overridepublic void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {System.out.print("<"+qName+">");}//读取到标签结束处调用@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {System.out.println("<"+qName+">");}//读取到标签内的文本内容时调用@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {System.out.print(new String(ch,start,length));}});//5.读取器解析XML文档reader.parse("src/user.xml");}}
功能:获取具体某个节点中的内容
package First.doing.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.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;public class UserNameHandler {/*** @param args* @throws SAXException * @throws ParserConfigurationException * @throws IOException */public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {//1.获取解析器工厂SAXParserFactory factory = SAXParserFactory.newInstance();//2.获取解析器SAXParser parser = factory.newSAXParser();//3.获取XML读取器XMLReader reader = parser.getXMLReader();//4.向读取器中注册处理器reader.setContentHandler(new DefaultHandler(){private String currentTag;private int count;@Overridepublic void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {currentTag = qName;if("职业".equals(qName))count++;}@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {if("职业".equals(currentTag) && count == 2){System.out.print(new String(ch,start,length));}}});//解析XML文档reader.parse("src/user.xml");}
}
功能:把XML文件中的关系数据用对象形式封装,并且把对象存入到ArrayList集合中
package First.doing.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;import First.doing.domain.Person;public class BeanListHandler {public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException{//1.创建Sax解析工厂SAXParserFactory factroy = SAXParserFactory.newInstance();//2.通过工厂方法建立解析器SAXParser parser = factroy.newSAXParser();//3.建立Xml文件读取器XMLReader reader = parser.getXMLReader();//向读取器中注册处理器List<Person> list = new ArrayList<Person>();MyListHandler handler = new MyListHandler();reader.setContentHandler(handler);//解析指定Xml文档reader.parse("src/user.xml");System.out.println(handler.getList().size());}
}class MyListHandler extends DefaultHandler{private List<Person> list = new ArrayList<Person>();private String currentTag;private Person person;@Overridepublic void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {currentTag = qName;if("用户".equals(qName))person = new Person();}@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {currentTag = "";if("用户".equals(qName))list.add(person);}@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {if("姓名".equals(currentTag))person.setName(new String(ch,start,length));if("年龄".equals(currentTag))person.setAge(new String(ch,start,length));if("职业".equals(currentTag))person.setJob(new String(ch,start,length));if("爱好".equals(currentTag))person.setHobby(new String(ch,start,length));}public List<Person> getList(){return list;}
}
5.dom4j工具包具体使用
注意:Node、Document、Element继承关系和JAXP中一样
SAXReader类
Constructor Summary | |
SAXReader() 构造解析器 |
Method Summary | |
Document | read(File file) 解析器读取文件File |
Document | read(URL url) 通过Url读取 |
Document | read(InputStream in) 通过读取流读取 |
Document | read(String systemId) 通过路径名读取 |
Document类
Method Summary | |
Element | getRootElement() 获取根节点 |
Element类
Method Summary | |
Element | element(String name) 获取名称为name 的子标签(name是子标签才能获取) |
Iterator | elementIterator(String name) 获取名称为name的子标签的全部子标签迭代器 |
List | elements() 把全部子标签元素存入一个List集合中 |
Iterator | elementIterator() 获取子标签迭代器 |
int | nodeCount() 获取子标签数,从父类Branch中继承的方法 |
Node | node(int index) 通过索引获取节点对象,从父类Branch中继承 |
Element | addElement(String name) 添加一个子标签,返回添加的子节点。不用自己重新创建 |
Element | addAttribute(String name,String value) 添加一个属性,返回自己。不用自己重新创建 |
Element | addText(String text) 添加内容,返回自己 |
String | attributeValue(String name) 返回name属性的值的字符串形式 |
DocumentHelper类
Method Summary | |
static Document | createDocument() 创建一个对象树 |
static Element | createElement(String name) 创建一个标签元素 |
XMLWriter类
Constructor Summary | |
XMLWriter(OutputStream out) 通过制定字节输出流构造对象(会把以utf-8编码的Document对象以utf-8编码写到本地文件中) | |
XMLWriter(OutputStream out,OutputFormat format) 传入输出流的基础上,指定一个标准输出格式 | |
XMLWriter(Writer writer) 通过制定字符输出流构造对象(读取Document对象时会查询编码表,然后把数据按照自定义指定的码表写到一个文件当中) | |
XMLWriter(Writer writer,OutputFormat format) 传入输出流的基础上,指定一个标准输出格式 |
Method Summary | |
void | write(Document doc) 把对象树写入到文件中 |
void | close() Closes the underlying Writer |
OutputFormat类
Method Summary | |
static OutputFormat | createCompactFormat() 获取无空格换行的输出格式 |
static OutputFormat | createPrettyPrint() 获取有优美格式的输出格式 |
void | setEncoding(String encoding) 能够指定输出流以哪种码表输出 |
代码实现
package Second.doing.dom4j;import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.List;import org.dom4j.Document;
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;public class dom4j_01 {//遍历Xml文档标签@Testpublic void listFile() throws Exception{SAXReader reader = new SAXReader();Document document = reader.read("src/user.xml");Element root = document.getRootElement();System.out.println(root.getName());Element user = root.element("用户");Element name = user.element("姓名");System.out.println(name.getName());System.out.println(name.getText());list(root);}public void list(Element e){System.out.println(e.getName());List<Element> list = e.elements();for(Element child : list)list(child);}//获取 <职业>学生</职业> 节点内容@Testpublic void getContent() throws Exception{SAXReader reader = new SAXReader();Document document = reader.read("src/user.xml");Element job = document.getRootElement().element("用户").element("职业");String content = job.getTextTrim();System.out.println(content);}//获取 <职业 avc="啊啊啊">学生</职业> 节点属性值@Testpublic void getAttribute() throws Exception{SAXReader reader = new SAXReader();Document document = reader.read("src/user.xml");Element job = document.getRootElement().element("用户").element("职业");String content = job.attributeValue("avc");System.out.println(content);}//向xml文档中添加一个<杰出程度>节点@Testpublic void addElement() throws Exception{SAXReader reader = new SAXReader();Document document = reader.read("src/user.xml");//创建要添加的结点内容属性并添加到指定位置Element newChild = document.getRootElement().element("用户").addElement("杰出程度").addAttribute("boolean", "ture").addText("垃圾");//运用格式化输出器修改编码方式OutputFormat format = OutputFormat.createPrettyPrint();format.setEncoding("utf-8");//把更新好的对象document回写到xml文档中XMLWriter writer = new XMLWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("src/user.xml"), "utf-8")),format);writer.write(document);writer.close();//注:如果让XMLWriter写数据到xml文档中,只会按着utf-8码表。如果xml文档是GB2312格式的,会把文档强转为utf-8的//为了防止乱码,应该用Format指定码表输出//add方法返回值为什么一般是添加的元素?因为这样便于在这个添加的节点上继续添加元素}//向xml文档指定位置添加 <杰出程度> 节点。@Testpublic void addElementOfSpecificLocation() throws Exception{SAXReader reader = new SAXReader();Document document = reader.read("src/user.xml");Element child = DocumentHelper.createElement("杰出程度");child.setText("哈哈");//在list集合指定位置添加元素 List<Element> list = document.getRootElement().element("用户").elements();list.add(2, child);//通过List集合添加元素在指定角标的方法//格式化回写的数据OutputFormat format = OutputFormat.createPrettyPrint();format.setEncoding("utf-8");//回写数据XMLWriter writer = new XMLWriter(new BufferedOutputStream(new FileOutputStream("src/user.xml")),format);writer.write(document);writer.close();}//删除和修改代码和dom类似就不再写了!}
XPath
dom4j中一种便捷取出指定节点的一种表达式语法。语法请看XPath文档很简单的
位置:jaxen-1.1 bata包中,所以在导入dom4j包的基础上还要导入这个开发包
Node接口
Method Summary | |
List | selectNodes(String xpathExpression) 返回按照XPath表达式查询到的所有标签对象的集合 |
Node | selectSingleNode(String xpathExpression) 返回按照XPath表达式查询到的所有标签对象的第一个节点 |
String | valueOf(String xpathExpression) 获取XPath表达式对应节点的字符串值 |
更多推荐
JavaEE开发——XML、DTD、Schema、Dom、Sax
发布评论