一、XML简介
1、xml的用途
html主要用于显示数据,xml也可以用于显示数据(不是主要功能)
xml主要功能:存储数据、数据的传输
2、xml的应用
不同系统之间传输数据
用来表示生活中有关系的数据
<?xml version="1.0" encoding="UTF-8"?>
<中国>
<河北>
<城市>张家口</城市>
<城市>石家庄</城市>
</河北>
<山西>
<城市>太原</城市>
<城市>大同</城市>
</山西>
</中国>
经常用在文件的配置
3、xml语法
文档声明:<?xml version="1.0" encoding="UTF-8"?>
(第一行第一列)
version:版本
encoding:编码
xml中文乱码的解决
保存时候的编码和设置打开时的编码一致
标签的定义
有开始必须有结束<A></A>
标签内没有内容可以在标签内结束
标签可以合理嵌套
一个xml文件有且仅有一个根标签
在xml中换行和空格都会当成代码解析
<?xml version="1.0" encoding="UTF-8"?>
<书架>
<书>
<书名><JavaWeb详解></书名>
<作者>张孝祥</作者>
<售价>58.00</售价>
</书>
<书>
<书名>EJB3.0入门经典</书名>
<作者>黎活明</作者>
<售价>39.00</售价>
</书>
<阿猫></阿猫>
</书架>
注意
1)<student/> 或 <student></student> 空标签。没有标签体内容
2)xml标签名称区分大小写。
3)xml标签一定要正确配对。
4)xml标签名中间不能使用空格
5)xml标签名不能以数字开头
注释
<!-- xml注释 -->
注释不能嵌套
注释不能放在第一行
xml中的特殊字符
特殊字符 转义字符
< <
> >
" "
& &
空格 &nsbp;
3、CDATA区
作用: 可以让一些需要进行包含特殊字符的内容统一进行原样输出。
写法:<![CDATA[ 内容 ]]>
4、PI指令(处理指令)
可以在xml中设置样式
只能对英文标签起作用
二、XML约束—DTD
1、DTD约束
步骤:
(1)、有几个元素就写几个<!ELEMENT>
(2)、判断元素是简单元素还是复杂元素
复杂元素:有子元素的元素
<!ELEMENT 元素名称 (子元素)>
简单元素:没有子元素的元素
<!ELEMENT 元素名称 (#PCDATA)>
引入dtd文件:<!DOCTYPE 根元素名称 SYSTEM "dtd文件路径">
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE 书架 SYSTEM "book.dtd">
<书架>
<书>
<书名><JavaWeb详解></书名>
<作者>张孝祥</作者>
<售价>58.00</售价>
</书>
<书>
<书名>EJB3.0入门经典</书名>
<作者>黎活明</作者>
<售价>39.00</售价>
</书>
<阿猫></阿猫>
</书架>
<!ELEMENT 书架 (书+)>
<!ELEMENT 书(书名,作者,售价)>
<!ELEMENT 书名(#PCDATA)>
<!ELEMENT 作者(#PCDATA)>
<!ELEMENT 售价(#PCDATA)>
2、dtd三种引入方式
1、外部引入:<!DOCTYPE 根元素名称 SYSTEM "dtd文件路径">
2、使用内部dtd文件:<!DOCTYPE 根元素名称{ }>
3、使用网络上的dtd文件:<!DOCTYPE 根元素名称 PUBLIC "dtd名称" "DTD文档的URL">
3、使用dtd定义元素
约束标签:<!ELEMENT 元素名称 类别>
或 <!ELEMENT 元素名称 (元素内容)>
类别:
空标签: EMPTY。 表示元素一定是空元素。
普通字符串: (#PCDATA)。表示元素的内容一定是普通字符串(不能含有子标签)。
任何内容: ANY。表示元素的内容可以是任意内容(包括子标签)
(元素内容):
顺序问题:用逗号,隔开
<!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,.....)>: 按顺序出现子标签
子元素若用竖线|
隔开则表示只能出现其中的一个
次数问题:
标签 : 必须且只出现1次。
标签+ : 至少出现1次
标签* : 0或n次。
标签? : 0 或1次。
约束属性
<!ATTLIST 元素名称 属性名称 属性类型 默认值>
默认值:
#REQUIRED 属性值是必需的
#IMPLIED 属性不是必需的
#FIXED value 属性不是必须的,但属性值是固定的
属性类型:控制属性值的
CDATA :表示普通字符串
(en1|en2|..): 表示一定是任选其中的一个值(枚举)
ID:表示在一个xml文档中该属性值必须唯一。值不能以数字开头
实体的定义:<!ENTITY 实体名称 "实体的值">
使用实体:&实体名称;
注意:定义的实体只能写在内部dtd中
三、XML约束—schema
1、特点
schema符合xml语法,xml语句
一个xml中可以有多个schema,多个schema使用名称空间区分(类似java中包名)
schema支持更多的数据类型
schema语法比dtd语法更加复杂
2、schema的基本语法.xsd
根节点:<schema>
在标签<schema>中的属性
xmlns="http://www.w3.org/2001/XMLSchema"
表示当前文件是一个约束文件
targetNamespace="http://www.example.org/NewSchema"
通过这个地址引入约束文件
elementFormDefault="qualified"
质量良好的
①、看xml中有多少个元素
②、看简单元素还是复杂元素,简单元素写在复杂元素的<sequence>里面
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/NewSchema"
xmlns:tns="http://www.example.org/NewSchema" elementFormDefault="qualified">
<element name="person">
<complexType>
<sequence>
<element name="name" type="string"></element>
<element name="age" type="int"></element>
</sequence>
</complexType>
</element>
</schema>
③、引入约束文件
xmlns:sht="http://www.w3.org/2001/XMLSchema-instance"
表示xml是一个被约束文件
xmlns="http://www.example.org/NewSchema"
是约束文档里面targetNamespace
sht:schemaLocation="http://www.example.org/NewSchema NewSchema.xsd"
targetNamespace 空格 约束文件的地址路径
<?xml version="1.0" encoding="UTF-8"?>
<person xmlns:sht="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.example.org/NewSchema"
sht:schemaLocation="http://www.example.org/NewSchema NewSchema.xsd">
<name>张三</name>
<age>20</age>
</person>
定义元素
<sequence>
有顺序的
<all>
只能出现一次
<choice>
只能出现所有元素其中的一个
<maxOccurs>
出现的次数,用在简单元素里面,unbounded表示无限次数
<any>
可以是任何元素
约束属性,写在复杂元素上
<attribute name="id1" type="int" use="required"></attribute>
必须要有一个id1的值
name属性名称 type数据类型 use属性是否必须出现required
<element name="person">
<complexType>
<sequence><!-- 有顺序的 -->
<element name="name" type="string" maxOccurs="unbounded"></element>
<element name="age" type="int"></element>
</sequence>
<attribute name="id1" type="int" use="required"></attribute>
</complexType>
</element>
<person xmlns:sht="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.example.org/NewSchema"
sht:schemaLocation="http://www.example.org/NewSchema NewSchema.xsd" id1="12">
<name>张三</name>
<age>20</age>
</person>
四、XML的解析
1、dom解析
DOM解析原理:xml解析器一次性把整个xml文档加载进内存,然后在内存中构建一颗Document的对象树,通过Document对象,得到树上的节点对象,通过节点对象访问(操作)到xml文档的内容。
优点:很方便实现增删改操作
缺点:若文件过大则易造成内存溢出
2、sax解析
采用事件驱动,边读边解析(从上到下一行一行的解析,解析到某一对象,返回对象的名称)
优点:不会造成内存的溢出,方便实现查询
缺点:不能实现增删改操作
3、解析器
sun公司提供了jaxp
dom4j组织提供了dom4j解析器(实际运用)
jdom组织提供了jdom解析器
4、使用dom4j来解析xml
首先导入dom4j的jar包
Dom4j工具(基于DOM解析原理):
读取xml文档:
Document doc = new SAXReader().read("xml文件");
节点:
nodeIterator(); 所有节点
标签:
element("名称") 指定名称的第一个子标签对象
elementIterator("名称"); 指定名称的所有子标签对象
elements(); 所有子标签对象
属性:
attributeValue(“名称”) 指定名称的属性值
attribute("名称") 指定名称的属性对象
getName() 属性名称
getValue() 属性值
atributeIterator() 所有属性对象(Iterator)
attributes() 所有属性对象(List)
文本:
getText() 得到当前标签的文本
elementText("子标签名称") 得到子标签的文本
获取父标签getParson();
得到根节点getRootElement();
使用dom4j查询xml文件内容
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class TestDom4j {
public static void main(String[] args) throws DocumentException {
//selectOne();
selectTwo();
}
//得到全部元素
public static void selectName() throws DocumentException{
/*
* 1、创建解析器
* 2、得到document
* 3、得到根节点
*
* 4、得到p1
* 5、得到name
* 6、得到name里面的值
*/
SAXReader sax = new SAXReader();
Document document = sax.read("src/day6/Test.xml");
//得到根节点
Element root = document.getRootElement();
//得到p1
List<Element> list = root.elements();
//遍历list
for (Element element1 : list) {
//element是每一个p1的元素
//得到p1下的name元素
Element name1 = element1.element("name");
//得到name里面的值
String str = name1.getText();
System.out.println(str);
}
}
//得到第一个元素的值
public static void selectOne() throws DocumentException {
/*
* 1、创建解析器 2、得到document 3、得到根节点
*
* 4、得到p1 5、得到name 6、得到name里面的值
*/
SAXReader sax = new SAXReader();
Document document = sax.read("src/day6/Test.xml");
// 得到根节点
Element root = document.getRootElement();
// 得到p1
Element element1 = root.element("p1");
// 得到p1下的name元素
Element name1 = element1.element("name");
// 得到name里面的值
String str = name1.getText();
System.out.println(str);
}
//得到第二个元素的值
public static void selectTwo() throws DocumentException {
/*
* 1、创建解析器 2、得到document 3、得到根节点
*
* 4、得到p1 5、得到name 6、得到name里面的值
*/
SAXReader sax = new SAXReader();
Document document = sax.read("src/day6/Test.xml");
// 得到根节点
Element root = document.getRootElement();
// 得到所有的p1
List<Element> list = root.elements();
//得到p2
Element p2 = list.get(1);
// 得到p2下的name元素
Element name2 = p2.element("name");
// 得到name里面的值
String str = name2.getText();
System.out.println(str);
}
}
5、使用Dom4j修改xml文档
1) 、写出内容到xml文档(回写)
OutputFormat format = OutputFormat.createPrettyPrint();
漂亮的格式
XMLWriter xmlwriter = new XMLWriter(OutputStream文件路径, format格式);
xmlwirter.write(Document);
写入xml文件
xmlwrite.close();
关闭流
2)、修改xml文档的API
增加:
DocumentHelper.createDocument() 增加文档
addElement("名称") 增加标签
addAttribute("名称",“值”) 增加属性
修改:
Attribute.setValue("值") 修改属性值
Element.addAtribute("同名的属性名","值") 修改同名的属性值
Element.setText("内容") 修改文本内容
删除
Element.detach(); 删除标签
Attribute.detach(); 删除属性
***添加一个标签在末尾
public static void add() throws Exception{
/*
* 1、创建解析器
* 2、得到document
* 3、得到根节点
*
* 4、得到p1
* 5、得到name
* 6、得到name里面的值
*/
SAXReader sax = new SAXReader();
Document document = sax.read("src/day6/Test.xml");
//得到根节点
Element root = document.getRootElement();
//得到第一个p1
Element p1 = root.element("p1");
//在p1下面直接添加元素
Element sex1 = p1.addElement("sex");
//给sex标签添加内容
sex1.setText("nan");
//回写xml文件
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter xmlwrite =new XMLWriter(new FileOutputStream("src/day6/Test.xml"), format);
xmlwrite.write(document);
xmlwrite.close();
}
获取标签里面属性的值:标签名.attributeValue("属性名称");
五、xPath技术
xPath作用
主要是用于快速获取所需的节点对象。
在dom4j中如何使用xPath技术
1)导入xPath支持jar包 。 jaxen-1.1-beta-6.jar
2)使用xpath方法
List<Node> selectNodes("xpath表达式"); 查询多个节点对象
Node selectSingleNode("xpath表达式"); 查询一个节点对象
xPath语法
/ 绝对路径 表示从xml的根位置开始或子元素(一个层次结构)
// 相对路径 表示不分任何层次结构的选择元素。
* 通配符 表示匹配所有元素
[] 条件 表示选择什么条件下的元素
@ 属性 表示选择属性节点
and 关系 表示条件的与关系(等价于&&)
ext() 文本 表示选择文本内容
学生管理系统案例
import java.io.FileOutputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.*;
public class StuService {
//增加
public static void addStu(Student student) throws Exception{
/*
* 1、创建解析器
* 2、得到document
* 3、获取到根节点
* 4、在根节点上添加<stu>标签
* 5、在stu标签上依次添加id name age
* 6、给id name age添加值
* 7、回写xml文件
*/
SAXReader saxreader = new SAXReader();
Document document = saxreader.read("src/student/student.xml");
Element root = document.getRootElement();
Element stu = root.addElement("stu");
Element id1 = stu.addElement("id");
Element name1 = stu.addElement("name");
Element age1 = stu.addElement("age");
//6、给id name age添加值
id1.setText(student.getId());
name1.setText(student.getName());
age1.setText(student.getAge());
//7、回写xml文件
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter xmlwrite = new XMLWriter(new FileOutputStream("src/student/student.xml"),format);
xmlwrite.write(document);
xmlwrite.close();
}
//删除
public static void removeStu(String id) throws Exception{
/*
* 1、创建解析器
* 2、得到document
* 3、获取到所有的id
* 4、遍历集合判断找到需要删除的结点id
* 5、回写xml文件
*/
SAXReader saxreader = new SAXReader();
Document document = saxreader.read("src/student/student.xml");
List<Node> list = document.selectNodes("//id");
for (Node node : list) {//node是集合中每个id
String str = node.getText();
if(str.equals(id)){//id相同
//获取stu节点
Element stu = node.getParent();
//获取到stu的父节点
Element student = stu.getParent();
//删除该节点
student.remove(stu);
}
}
//回写xml文件
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter xmlwrite = new XMLWriter(new FileOutputStream("src/student/student.xml"),format);
xmlwrite.write(document);
xmlwrite.close();
}
//查询
public static Student selectStu(String id) throws Exception{
SAXReader saxreader = new SAXReader();
Document document = saxreader.read("src/student/student.xml");
Student student = new Student();
List<Node> list = document.selectNodes("//id");
for (Node node : list) {//node是集合中每个id
String str = node.getText();
if(str.equals(id)){//id相同
//获取stu节点
Element stu = node.getParent();
//获取name age的值
String name1 = stu.element("name").getText();
String age1 = stu.element("age").getText();
student.setId(str);
student.setName(name1);
student.setAge(age1);
}
}
return student;
}
}
网友评论