XML简介
XML(EXtensibel Markup Language),可扩展标记语言
特点:
- XML与操作系统、编程语言的开发平台无关
- 实现不同系统之间的数据交换
作用
- 数据交互
- 配置应用程序和网站
- Ajax基石
框架配置文件是XML格式的。
XML文档结构
XML的声明
<?xml version="1.0" standalone="yes" encoding="UTF-8”?>
这是一个XML处理指令。处理指令以 <? 开始,以 ?> 结束。<? 后的第一个单词是指令名,如xml, 代表XML声明。
version, standalone, encoding 是三个特性,特性是由等号分开的名称-数值对,等号左边是特性名称,等号右边是特性的值,用引号引起来。
- version: 说明这个文档符合1.0规范
- standalone: 说明文档在这一个文件里还是需要从外部导入, standalone 的值设为yes 说明所有的文档都在这一文件里完成
- encoding: 指文档字符编码
根元素定义
XML文档的树形结构要求必须有一个根元素。根元素的起始标记要放在所有其它元素起始标记之前,根元素的结束标记根放在其它所有元素的结束标记之后
<?xml version="1.0" encoding="UTF-8"?>
<根元素>
<元素 属性 = "值">
<属性>值</属性>
</元素>
<元素 属性 = "值" 属性 = "值" 属性 = "值"/>
</根元素>
XML标签
XML由一系列 标签元素组成
<元素名 属性名=>“属性值”>元素内容</元素名>
空元素:
- <name> </name>
- <name></name>
- </name>
语法
属性值引用双引号包裹
一个元素可以有多个属性
属性值中不能直接包含<、&。
示例:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 格式测试 -->
<student>
<student id = "s1">
<name>王五</name>
<age>66</age>
</student>
<student id = "s2">
<name>高达</name>
<age>1000</age>
</student>
<student id = "s3" name = "蝙蝠侠" age = "50"/>
</student>
不一样的浏览器,提示的错误不一样。
XML编写注意事项
标签编写注意事项
- 所有XML元素都必须有结束标签
- XML标签对大小写敏感
- XML必须正确的嵌套
- 统计表前以缩进对齐
- 元素名称可以包含字母、数字或其他的字符
- 元素名称不能以数字或者标点符号开始
- 元素名称中不能包含空格
- 可以使用下划线拼接较长名称,但不能使用.、:拼接
转义符
符号 | 转义符 |
---|---|
< | <; |
> | >; |
“ | "; |
‘ | &apos; |
& | &; |
当元素中出现很多特殊字符时,可以使用CDATA节。
示例:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 测试转义字符 -->
<clothes>
<size range = "155<身高<160">S</size>
<size range = "165<身高<170">M</size>
<size range = "170<身高<175">L</size>
<size range = "175<身高<180">XL</size>
<explain><![CDATA[155<升高<160是&&M号]]></explain>
</clothes>
XML解析器
解析器类型
-
非验证解析器
- 检查文档格式是否良好
-
验证解析器
- 使用DTD检查文档的有效性
DTD(Document Type Define)验证机制
XML 命名空间(XML Namespaces)
命名冲突
在 XML 中,元素名称是由开发者定义的,当两个不同的文档使用相同的元素名时,就会发生命名冲突。
XML命名空间的作用
XML 命名空间提供避免元素命名冲突的方法。
解析XML技术
DOM
- 基于XML文档书结构的解析
- 适用于多次访问的XML文档
- 特点:比较消耗资源
DOM把XML文档映射成一个倒挂的树
- 元素节点
- 文档节点
- 属性节点
SAX
-
基于时间的解析
-
使用于大数据量的XML文档
-
特点:占用资源少,内存消耗小
DOM4J
-
非常优秀的Java XMLAPI
-
性能优异、功能强大
-
开放源代码
常用接口介绍
DOM解析包:org.w3c.dom
访问DOM数节点
DOM解析XML文件步骤
- 创建解析器工厂对象
- 解析器工厂对象创建解析器对象
- 解析器对象指定XML文件创建Document对象
- 以Document对象为起点操作DOM树
实例:
/**
* 使用DOM解析XML文件
* @author 周太阳
* @version 1.0
* 2019年5月1日 上午11:40:20
*/
public class ParseXMLDemo {
/** 创建一个Document成员属性*/
private Document document;
/**
* 得到DOM树存入Document
*/
public void getDom() {
// 创建一个解析工厂对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
// 解析器工厂对象创建解析器对象
DocumentBuilder db = dbf.newDocumentBuilder();
// 解析XML文件并传给Document对象
document = db.parse("src/kgc/april/thirty/xml/收藏信息.xml");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取手机品牌和相关信息
*/
public void showInfo() {
// 得到对应的元素子节点
NodeList elementBrand = document.getElementsByTagName("brand");
// 遍历子节点
for (int i = 0; i < elementBrand.getLength(); i++) {
// 获得子节点并存入Node集合
Node item = elementBrand.item(i);
// 节点强转为元素
Element element = (Element)item;
// 获取元素对应属性的值
String brandName = element.getAttribute("name");
System.out.println(brandName);
// 遍历子元素
NodeList types = element.getChildNodes();
for (int j = 0; j < types.getLength(); j++) {
// 得到每个子节点
Node item2 = types.item(j);
// 筛选节点
if (item2.getNodeType() == item2.ELEMENT_NODE) {
// 节点转换为元素
Element type = (Element)item2;
System.out.println("\t"+type.getAttribute("name"));
}
}
}
}
/**
* 往XML里添加元素
*/
public void addElement() {
// 添加一个brand元素
Element newBrand = document.createElement("brand");
// 设置brand的属性
newBrand.setAttribute("name", "三星");
// 添加一个type元素
Element newType = document.createElement("type");
// 设置type的属性
newType.setAttribute("name", "Note3");
// 将type元素设置为brand的子元素
newBrand.appendChild(newType);
// 将brand元素放到phone节点中去
document.getElementsByTagName("phone").item(0).appendChild(newBrand);
}
/**
* 在元素中添加属性
*/
public void updata() {
// 获得brand标签名的子节点
NodeList elebrand = document.getElementsByTagName("brand");
// 遍历NodeList集合
for (int i = 0; i < elebrand.getLength(); i++) {
// 获取每一个子节点
Node item = elebrand.item(i);
// 强转为元素
Element element = (Element)item;
// 添加属性
element.setAttribute("id", i+"");
}
}
/**
* 删除元素
*/
public void deleteEle() {
// 取出brand的子节点放到NodeList集合里
NodeList eleBrand = document.getElementsByTagName("brand");
// 遍历Node集合
for (int i = 0; i < eleBrand.getLength(); i++) {
// 得到每一个子节点
Node item = eleBrand.item(i);
// 强转为元素
Element element = (Element)item;
// 如果是要删除的元素
if (element.getAttribute("name").equals("三星")) {
// 用父节点删除子节点
element.getParentNode().removeChild(element);
}
}
}
/**
* 将新的DOM树添加进XML文件
* @param pathname xml路径
*/
public void saveDom() {
// 创建转换器工场
TransformerFactory tff = TransformerFactory.newInstance();
// 设置转换器工场格式,缩进4个字符
tff.setAttribute("indent-number", 4);
try {
// 用转换器工场创建转换器
Transformer tf = tff.newTransformer();
// 使用转换器设置编码
tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
// 使用转换器设置允许缩进
tf.setOutputProperty(OutputKeys.INDENT, "yes");
// 建立字节输出流并传入XML文件路径
FileOutputStream fos = new FileOutputStream("src/kgc/april/thirty/xml/收藏信息.xml");
// 建立结果流
StreamResult sw = new StreamResult(new OutputStreamWriter(fos,"UTF-8"));
// 将最新的DOM变成源
DOMSource source = new DOMSource(document);
// 写入XML文件
tf.transform(source,sw);
} catch (TransformerConfigurationException e) {
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// 创建对象
ParseXMLDemo xmlDemo = new ParseXMLDemo();
// 调用获得Document方法
xmlDemo.getDom();
// 增加元素
xmlDemo.addElement();
// 在元素中添加新的属性
xmlDemo.updata();
// 删除元素
xmlDemo.deleteEle();
// 保存新的DOM树到XML文件
xmlDemo.saveDom();
// 得到手机信息
xmlDemo.showInfo();
}
}