XML以及dom4j
-
SGML(Standard Generalized Markup Language,标准通用标记语言)就已存在,正如它的名称所言,SGML是国际上定义电子文件结构和内容描述的标准。SGML具有非常复杂的文档结构,主要用于大量高度结构化数据的访问和其他各种工业领域,在分类和索引数据中非常有用。
-
HTML是一种界面技术,它只使用了SGML中很少的一部分标记,例如HTML 4.0中只定义了70余种标记。为了便于在计算机上实现,HTML规定的标记是固定的,即HTML语法是不可扩展的。
XML(EXtensible Markup Language),可扩展标记语言
xml是一种用于标记电子文件使其具有结构性的标记语言。XML 被设计用来传输和存储数据,其焦点是数据的内容。
特点:
- XML与操作系统、编程语言的开发平台无关
- 实现不同系统之间的数据交换
作用:
-
数据交互(数据传输)
-
配置应用程序和网站
-
Ajax基石
文档格式:
XML是纯文本格式, 每个XML元素包括一个开始标记(),一个结束标记()以及两个标记之间的内容
-
具体规则:
-
必须有声明语句,在文档第一句
<?xml version="1.0" encoding="utf-8"?> version:文档符合xml1.0规范 encoding:文档字符编码,默认UTF-8
-
注意大小写
在XML文档中,大小写是有区别的。 前后标记的大小写要保持一致。全部大写,或者全部小写,或者大写第一个字母,这样可以减少因为大小写不匹配而产生的文档错误。
-
XML文档只有一个根元素
良好格式的XML文档必须有一个根元素,就是紧接着声明后面建立的第一个元素,其他元素都是这个根元素的子元素
-
属性值使用引号
在HTML代码里面,属性值可以加引号,也可以不加。但是XML规定,所有属性值必须加引号(可以是单引号,也可以是双引号,建议使用双引号),否则将被视为错误 。
-
XML标签:
<元素名 属性名=“属性值”> 元素内容 </元素名>
- 属性值用双引号包裹
- 一个元素可以有多个属性
- 属性值中不能直接包含<、“、&
- 不建议使用的字符:‘、>
XML编写注意事项 :
-
所有XML元素都必须有结束标签
-
XML标签对大小写敏感
-
XML必须正确的嵌套
-
同级标签以缩进对齐
-
元素名称可以包含字母、数字或其他的字符
-
元素名称不能以数字或者标点符号开始
-
元素名称中不能含空格
<?xml version="1.0" encoding="UTF-8"?>
<books>
<!--图书信息 -->
<book id="bk101">
<author>王珊</author>
<title>.NET高级编程</title>
<description>包含C#框架和网络编程等</description>
</book>
<book id="bk102">
<author>李明明</author>
<title>XML基础编程</title>
<description>包含XML基础概念和基本作用</description>
</book>
</books>
XML解析器:
- 非验证性解析器:检查文档格式是否良好
- 使用DTD检查文档的有效性
DTD:
Document Type Definition:文档类型定义,用于约束xml的文档格式,保证xml是一个有效的xml。分内部DTD和外部DTD
使用DTD:
-
内部DTD:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE 根元素 [元素声明]> <!ATTList 元素名称 属性名称 属性类型 默认值> //*任意次 ; ? 0次或者1次 ; +至少出现一次 <!DOCTYPE score [ <!ELEMENT score (student*)> <!ELEMENT score (name,yuji.shiji)> <!ATTLIST student id CDATA #REQUIRED> //声明属性 <!ELEMENT name (#PCDATA)> //标签name内部不能再有标签 ]>
属性类型:CDATA,表示字符数据
默认值:
#REQUIRED,表示必须出现
#IMPLIED,表示不是必须的
-
外部DTD
DTD文件:
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT scores (student+)> <!ELEMENT student (name,course,score)> <!ATTLIST student id CDATA #REQUIRED> <!ELEMENT name (#PCDATA)> <!ELEMENT course (#PCDATA)>
在xml中引用DTD文件:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE score SYSTEM "score.dtd">
解析XML技术:
- DMO:基于XML文档树结构的解析;适用于多次访问的XML文档;比较消耗资源
- SAX:基于事件的解析;适用于大数据量的XML文档
- JDOM解析:第三方提供,免费开源的解析方式,比DOM解析快。
- DOM4J:非常优秀的Java XML API;性能优异、功能强大;开放源代码;使用接口而不使用类。 是JDOM的升级版 。
1.DOM解析xml
文档对象模型(Document Object Model);DOM把XML文档映射成一个倒挂的树
常用接口介绍
常用接口 | 常用方法 | 说明 |
---|---|---|
Document:表示整个 XML 文档 | NodeList getElementsByTagName(String Tag) | 按文档顺序返回文档中指定标记名称的所有元素集合 |
Element createElement(String tagName) | 创建指定标记名称的元素 | |
Node:该文档树中的单个节点 | NodeList getChildNodes() | 获取该元素的所有子节点,返回节点集合 |
Element:XML 文档中的一个元素 | String getTagName() | 获取元素名称 |
DOM解析XML文件步骤
-
创建解析器工厂对象
-
解析器工厂对象创建解析器对象
-
解析器对象指定XML文件创建Document对象
-
以Document对象为起点操作DOM树
2.DIM4J解析已有XML:
解析xml的入口,是需要先拿到一个Document对象。
准备好的xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<score>
<student id = "haha">
<name>学生1</name>
<yuji>75</yuji>
<shiji>80</shiji>
</student>
<student>
<name>学生2</name>
<yuji>75</yuji>
<shiji>88</shiji>
</student>
</score>
解析XML:
public static void main(String[] args) throws DocumentException{
//创建SAXReader或者DOMReader对象,用于读取xml文件
SAXReader reader = new SAXReader();
//读取xml文件,得到Document对象
Document doc = reader.read(new File("src/score.xml"));
//System.out.println(doc);
//获取根元素
Element rootElement = doc.getRootElement();
//获取根元素下所有子元素
Iterator<?> it = rootElement.elementIterator();
while(it.hasNext()){
Element e = (Element)it.next();
//System.out.println(e.getName());
//获取id属性
Attribute id = e.attribute("id");
//System.out.println(id.getName()+"="+id.getValue());
System.out.println("----------------");
//获取Student子元素
Element name = e.element("name");
Element yuji = e.element("yuji");
Element shiji = e.element("shiji");
System.out.println(name.getName()+"="+name.getStringValue());
System.out.println(yuji.getName()+"="+yuji.getText());
System.out.println(shiji.getName()+"="+shiji.getText());
}
}
3.DOM4j生成XML文件:
/**
* dom4j生成xml
* @author Lenovo
*
*/
public class Test02 {
public static void main(String[] args) throws Exception {
//[1]通过DocumentHelper生成一个Document对象
Document doc = DocumentHelper.createDocument();
//链式编程
//doc.addElement("books").addElement("book").addAttribute("id", "bookone");
//[2]添加根元素,并返回
Element root = doc.addElement("books");
//[3]为根元素添加子元素
Element book = root.addElement("book");
//[4]添加属性
book.addAttribute("id", "bookone");
//[5]为book添加子元素
Element name = book.addElement("name");
Element author = book.addElement("author");
Element price = book.addElement("price");
//[6]为子元素添加文本
name.addText("小王子");
author.addText("圣埃克苏佩里");
price.addText("20");
//[7]将doc输出到xml文件中
// Writer ww = new FileWriter(new File("src/book2.xml"));
// doc.write(ww);
//格式美化实例:
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter ww = new XMLWriter(new FileWriter(new File("src/book2.xml")),format);
ww.write(doc);
ww.close();
}
}
输出格式设置:百度连接:https://baike.baidu.com/item/dom4j/828750?fr=aladdin
5.xml内容的添加(相当于覆盖)
还是读取xml文件的方法,用addXXX进行元素、属性、文本的添加
public static void main(String[] args) {
try {
SAXReader reader = new SAXReader();
Document doc = reader.read("score.xml");
Element score = doc.getRootElement(); //根节点
Element student = score.addElement("student"); //根节点下再加子结点
student.addAttribute("delete", "学生四");
//子节点下再加东西
Element name = student.addElement("name");
name.setText("撒白气球");
Element yuji = student.addElement("yuji");
yuji.setText("90");
Element shiji = student.addElement("shiji");
shiji.setText("100");
System.out.println("修改成功");
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter ww = new XMLWriter(new FileWriter(new File("score.xml")),format);
format.setEncoding("GBK");
ww.write(doc);
ww.close();
} catch (Exception e) {
e.printStackTrace();
}
}
6.删除节点内容
读取xml文件,找自己要删除的节点。在用 remove()方法的时候注意和 getParent()方法搭配使用。
当找到xx节点要删除,要先 xx.getParent()得到其父节点,在remove(),即 xxx.getParent().remove(xxx);
public static void main(String[] args) {
try {
SAXReader reader = new SAXReader();
Document doc = reader.read("phone.xml");
Element phone = doc.getRootElement(); //根节点
List<Element> list = phone.elements();
for(Element el : list){
List<Element> brand = el.elements();
for(Element type : brand){
if(type.getText().equals("HW321")){
type.getParent().remove(type);
}
}
}
System.out.println("删除成功!");
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter ww = new XMLWriter(new FileWriter(new File("phone.xml")),format);
format.setEncoding("GBK");
ww.write(doc);
ww.close();
} catch (Exception e) {
e.printStackTrace();
}
}
后面有与使用socket TCP协议编写服务端与客户端与xml文件的结合例子,下次再说,后续想看我会放链接