<中国>
<北京>
<大兴>幸福家园大兴>
北京>
<河北>
<石家庄/>
河北>
中国>
1. 文档声明
1. 注意1:有且仅有一个
2. 注意2:必须首行,前面不能有任何内容
3. 注意3:没有文档声明,是一个格式不良好的xml
4. 注意4:文档的编码和文档保存时的编码必须一致
2. 元素:一个标签就是一个元素<中国>中国>
1. 注意1:开始标签和结束标签
2. 注意2:自闭标签
3. 注意3:根标签--一个xml文档有且仅有一个
4. 注意4:可以标签嵌套,但不能出现交叉嵌套
5. 命名规范
1. 区分大小写
2. 不能以数字开头
3. 不能以xml,Xml,XMl开头
4. 不能包含空格
5. 不能包含冒号
3. 属性
1. 注意1:一个标签可以有多个属性,多个属性用空格隔开,属性值用双引号或单引号引起来
2. 注意2:属性和元素具有相同的命名规范
4. 注释
1. 格式:
2. 注意:
1. 不能放在文档生命的上面
2. 注释不能交叉嵌套
5. 转义字符
1. < <
2. > >
3. " "
4. ' '
5. & &
xml解析:两种解析方式【DOM解析和Sax解析】
1. 可以十分方便对节点进行增删改查
2. 在内存中保存了一颗文档结构树,只需解析一次就可以重复使用这些数据
1. 占用内存--一次加载
2. 耗费时间--如果文档太大
1. 占用内存小--不需要将整个文档加载到内存,逐行加载
2. 逐行解析,可以在任何地方停下来,效率高
1. 每次需要数据重新解析
2. 只能读取,不能增删改
Dom4j解析:dom4j是一个开源的xml解析包,具有性能优异、功能强大和极易使用的特点。
<书架>
<书>
<书名>数据结构书名>
<作者>严蔚敏作者>
<售价>29.00 元售价>
书>
<书>
<书名>高等数学书名>
<作者>同济大学数学系作者>
<售价>55.00 元售价>
书>
书架>
主函数(第一种)
package com.peng.xmldemo;
import java.io.File;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* @author kungfu~peng
* @data 2017年11月14日
* @description xml解析
*/
public class XmlDemo {
public static void main(String[] args) throws DocumentException {
// 创建解析器
SAXReader reader = new SAXReader();
// 获得xml文件
Document doc = reader.read(new File("src/book.xml"));
//获得根节点--“书架”
Element root = doc.getRootElement();
//获取第一个节点--“书”
Element book_1=root.element("书");
//获取第一个书名节点--“书名”
Element book_1_1=book_1.element("书名");
//获取书名的内容--具体的
System.out.println(book_1_1.getText());
}
}
主函数(第二种)
package com.peng.xmldemo;
import java.io.File;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* @author kungfu~peng
* @data 2017年11月14日
* @description xml解析
*/
public class XmlDemo {
public static void main(String[] args) throws DocumentException {
// 创建解析器
SAXReader reader = new SAXReader();
// 获得xml文件
Document doc = reader.read(new File("src/book.xml"));
// 获得根节点--“书架”
Element root = doc.getRootElement();
// 获取所有第一层节点
List list = root.elements();
// 遍历
for (Element e : list) {
System.out.println(e.element("书名").getText() + "\t"
+ e.element("售价").getText() + "\t"
+ e.element("作者").getText());
}
}
}
获取Document成一个函数
package com.peng.xmldemo;
import java.io.File;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* @author kungfu~peng
* @data 2017年11月14日
* @description xml解析
*/
public class XmlDemo {
public static void main(String[] args) {
Document doc=getDoc("src/book.xml");
}
/**
* 功能:获取document对象 返回值类型:Document 参数列表:String xmlPath
*/
private static Document getDoc(String xmlPath) {
Document dom = null;
try {
SAXReader reader = new SAXReader();
dom = reader.read(new File(xmlPath));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
return dom;
}
}
添加节点--方法1
package com.peng.xmldemo;
import java.io.File;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* @author kungfu~peng
* @data 2017年11月14日
* @description xml解析
*/
public class XmlDemo {
public static void main(String[] args) {
Document doc = getDoc("src/book.xml");
// 获取根节点
Element root = doc.getRootElement();
// 获取第一本书
Element book_1 = root.element("书");
// 创建一个游离的节点--方式1
Element pe1 = DocumentHelper.createElement("特价");
// 为游离的节点进行赋值
pe1.setText("9.9元");
// 将游离的 节点挂载到第一本书上
book_1.add(pe1);
// 打印新的元素内容
System.out.println(book_1.element("特价").getText());
}
/**
* 功能:获取document对象 返回值类型:Document 参数列表:String xmlPath
*/
private static Document getDoc(String xmlPath) {
Document dom = null;
try {
SAXReader reader = new SAXReader();
dom = reader.read(new File(xmlPath));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
return dom;
}
}
添加一个节点--方式2
package com.peng.xmldemo;
import java.io.File;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* @author kungfu~peng
* @data 2017年11月14日
* @description xml解析
*/
public class XmlDemo {
public static void main(String[] args) {
Document doc = getDoc("src/book.xml");
// 获取根节点
Element root = doc.getRootElement();
// 获取第一本书
Element book_1 = root.element("书");
// 添加节点--方式2
Element pe1 = book_1.addElement("特价");
// 为节点进行赋值
pe1.setText("8.8元");
// 打印新的元素内容
System.out.println(book_1.element("特价").getText());
}
/**
* 功能:获取document对象 返回值类型:Document 参数列表:String xmlPath
*/
private static Document getDoc(String xmlPath) {
Document dom = null;
try {
SAXReader reader = new SAXReader();
dom = reader.read(new File(xmlPath));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
return dom;
}
}
将更新的document写入xml,并加入格式输入器
package com.peng.xmldemo;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
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;
/**
* @author kungfu~peng
* @data 2017年11月14日
* @description xml解析
*/
public class XmlDemo {
public static void main(String[] args) throws Exception {
Document doc = getDoc("src/book.xml");
// 获取根节点
Element root = doc.getRootElement();
// 获取第一本书
Element book_1 = root.element("书");
// 添加节点--方式2
Element pe1 = book_1.addElement("特价");
// 为节点进行赋值
pe1.setText("8.8元");
//将更新的document写入到xml中,并加入格式输入器
XMLWriter writer =new XMLWriter(new FileOutputStream(new File("src/book.xml")),OutputFormat.createPrettyPrint());
writer.write(doc);
writer.close();
}
/**
* 功能:获取document对象 返回值类型:Document 参数列表:String xmlPath
*/
private static Document getDoc(String xmlPath) {
Document dom = null;
try {
SAXReader reader = new SAXReader();
dom = reader.read(new File(xmlPath));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
return dom;
}
}
//执行完结果
<书架>
<书>
<书名>数据结构书名>
<作者>严蔚敏作者>
<售价>29.00 元售价>
<特价>8.8元特价>
书>
<书>
<书名>高等数学书名>
<作者>同济大学数学系作者>
<售价>55.00 元售价>
书>
书架>
代码抽取简化
package com.peng.xmldemo;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
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;
/**
* @author kungfu~peng
* @data 2017年11月14日
* @description xml解析
*/
public class XmlDemo {
public static void main(String[] args) throws Exception {
Document doc = getDoc("src/book.xml");
// 获取根节点
Element root = doc.getRootElement();
// 获取第一本书
Element book_1 = root.element("书");
// 添加节点--方式2
Element pe1 = book_1.addElement("特价");
// 为节点进行赋值
pe1.setText("8.8元");
// 重新写入文件
writeToXml(doc, "src/book.xml");
}
/**
* 功能:获取document对象 返回值类型:Document 参数列表:String xmlPath
*/
private static Document getDoc(String xmlPath) {
Document dom = null;
try {
SAXReader reader = new SAXReader();
dom = reader.read(new File(xmlPath));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
return dom;
}
/**
* 功能:将修改后的xml文件保存 返回值类型:void 参数列表:(Document document,String xmlPath)
*
*/
private static void writeToXml(Document document, String xmlPath)
throws Exception {
// 将更新的document写入到xml中,并加入格式输入器
XMLWriter writer = new XMLWriter(
new FileOutputStream(new File(xmlPath)),
OutputFormat.createPrettyPrint());
writer.write(document);
writer.close();
}
}
节点的增删改查--通过List来进行操作
//元数据
<书架>
<书>
<书名>数据结构书名>
<作者>严蔚敏作者>
<售价>29.00 元售价>
书>
<书>
<书名>高等数学书名>
<作者>同济大学数学系作者>
<售价>55.00 元售价>
书>
书架>
//主函数
package com.peng.xmldemo;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
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;
/**
* @author kungfu~peng
* @data 2017年11月14日
* @description xml解析
*/
public class XmlDemo {
public static void main(String[] args) throws Exception {
Document doc = getDoc("src/book.xml");
// 获取根节点
Element root = doc.getRootElement();
// 获取第一层所有节点
List list_1 = root.elements();
// 获取第一层的第二个节点的所有子节点
List list_1_2 = list_1.get(1).elements();
// 给第一层的第二个节点的子节点添加一个节点
Element temp = DocumentHelper.createElement("特价");
temp.setText("7.7元");
list_1_2.add(1, temp);
// 删除第一层的第二个节点的第一个子节点
list_1_2.remove(0);
// 修改第一层的第二个节点的第二个子节点
list_1_2.get(1).setText("修改了的节点内容");
// 查看第一层的所有节点
for (Element e : list_1_2) {
System.out.println(e.getName());
}
// 重新写入文件
writeToXml(doc, "src/book.xml");
}
/**
* 功能:获取document对象 返回值类型:Document 参数列表:String xmlPath
*/
private static Document getDoc(String xmlPath) {
Document dom = null;
try {
SAXReader reader = new SAXReader();
dom = reader.read(new File(xmlPath));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
return dom;
}
/**
* 功能:将修改后的xml文件保存 返回值类型:void 参数列表:(Document document,String xmlPath)
*
*/
private static void writeToXml(Document document, String xmlPath)
throws Exception {
// 将更新的document写入到xml中,并加入格式输入器
XMLWriter writer = new XMLWriter(
new FileOutputStream(new File(xmlPath)),
OutputFormat.createPrettyPrint());
writer.write(document);
writer.close();
}
}
//修改后的数据
<书架>
<书>
<书名>数据结构书名>
<作者>严蔚敏作者>
<售价>29.00 元售价>
书>
<书>
<特价>7.7元特价>
<作者>修改了的节点内容作者>
<售价>55.00 元售价>
书>
书架>
//输出结果
特价
作者
售价
//补充:另外一种删除子节点的方式
package com.peng.xmldemo;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
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;
/**
* @author kungfu~peng
* @data 2017年11月14日
* @description xml解析
*/
public class XmlDemo {
public static void main(String[] args) throws Exception {
Document doc = getDoc("src/book.xml");
// 获取根节点
Element root = doc.getRootElement();
// 获取第一个书节点
Element e_1 = root.element("书");
// 找要删除的书名节点
Element delElement = e_1.element("书名");
// 删除节点
e_1.remove(delElement);
// 重新写入文件
writeToXml(doc, "src/book.xml");
}
/**
* 功能:获取document对象 返回值类型:Document 参数列表:String xmlPath
*/
private static Document getDoc(String xmlPath) {
Document dom = null;
try {
SAXReader reader = new SAXReader();
dom = reader.read(new File(xmlPath));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
return dom;
}
/**
* 功能:将修改后的xml文件保存 返回值类型:void 参数列表:(Document document,String xmlPath)
*
*/
private static void writeToXml(Document document, String xmlPath)
throws Exception {
// 将更新的document写入到xml中,并加入格式输入器
XMLWriter writer = new XMLWriter(
new FileOutputStream(new File(xmlPath)),
OutputFormat.createPrettyPrint());
writer.write(document);
writer.close();
}
}
添加属性
第一种方式
package com.peng.xmldemo;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.dom4j.Attribute;
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;
/**
* @author kungfu~peng
* @data 2017年11月14日
* @description xml解析
*/
public class XmlDemo {
public static void main(String[] args) throws Exception {
Document doc = getDoc("src/book.xml");
// 获取根节点
Element root = doc.getRootElement();
// 获取第一个书节点
Element e_1 = root.element("书");
// 创建属性version
Attribute version = DocumentHelper.createAttribute(e_1, "version", "1.0");
//添加属性
e_1.add(version);
// 重新写入文件
writeToXml(doc, "src/book.xml");
}
/**
* 功能:获取document对象 返回值类型:Document 参数列表:String xmlPath
*/
private static Document getDoc(String xmlPath) {
Document dom = null;
try {
SAXReader reader = new SAXReader();
dom = reader.read(new File(xmlPath));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
return dom;
}
/**
* 功能:将修改后的xml文件保存 返回值类型:void 参数列表:(Document document,String xmlPath)
*
*/
private static void writeToXml(Document document, String xmlPath)
throws Exception {
// 将更新的document写入到xml中,并加入格式输入器
XMLWriter writer = new XMLWriter(
new FileOutputStream(new File(xmlPath)),
OutputFormat.createPrettyPrint());
writer.write(document);
writer.close();
}
}
第二种方式
package com.peng.xmldemo;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.dom4j.Attribute;
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;
/**
* @author kungfu~peng
* @data 2017年11月14日
* @description xml解析
*/
public class XmlDemo {
public static void main(String[] args) throws Exception {
Document doc = getDoc("src/book.xml");
// 获取根节点
Element root = doc.getRootElement();
// 获取第一个书节点
Element e_1 = root.element("书");
// 添加属性
e_1.addAttribute("version", "2.0");
// 重新写入文件
writeToXml(doc, "src/book.xml");
}
/**
* 功能:获取document对象 返回值类型:Document 参数列表:String xmlPath
*/
private static Document getDoc(String xmlPath) {
Document dom = null;
try {
SAXReader reader = new SAXReader();
dom = reader.read(new File(xmlPath));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
return dom;
}
/**
* 功能:将修改后的xml文件保存 返回值类型:void 参数列表:(Document document,String xmlPath)
*
*/
private static void writeToXml(Document document, String xmlPath)
throws Exception {
// 将更新的document写入到xml中,并加入格式输入器
XMLWriter writer = new XMLWriter(
new FileOutputStream(new File(xmlPath)),
OutputFormat.createPrettyPrint());
writer.write(document);
writer.close();
}
}
查询属性
package com.peng.xmldemo;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.dom4j.Attribute;
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;
/**
* @author kungfu~peng
* @data 2017年11月14日
* @description xml解析
*/
public class XmlDemo {
public static void main(String[] args) throws Exception {
Document doc = getDoc("src/book.xml");
// 获取根节点
Element root = doc.getRootElement();
// 获取第一个书节点
Element e_1 = root.element("书");
// 获取属性--方式1
System.out.println(e_1.attribute(0).getName() + ":"
+ e_1.attribute(0).getValue());
// 获取属性--方式2
System.out.println(e_1.attribute("version").getName() + ":"
+ e_1.attribute("version").getValue());
// 获取属性--方式3
System.out.println(e_1.attributeValue("version"));
// 重新写入文件
writeToXml(doc, "src/book.xml");
}
/**
* 功能:获取document对象 返回值类型:Document 参数列表:String xmlPath
*/
private static Document getDoc(String xmlPath) {
Document dom = null;
try {
SAXReader reader = new SAXReader();
dom = reader.read(new File(xmlPath));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
return dom;
}
/**
* 功能:将修改后的xml文件保存 返回值类型:void 参数列表:(Document document,String xmlPath)
*
*/
private static void writeToXml(Document document, String xmlPath)
throws Exception {
// 将更新的document写入到xml中,并加入格式输入器
XMLWriter writer = new XMLWriter(
new FileOutputStream(new File(xmlPath)),
OutputFormat.createPrettyPrint());
writer.write(document);
writer.close();
}
}
删除属性
addAttribute("",null);
package com.peng.xmldemo;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.dom4j.Attribute;
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;
/**
* @author kungfu~peng
* @data 2017年11月14日
* @description xml解析
*/
public class XmlDemo {
public static void main(String[] args) throws Exception {
Document doc = getDoc("src/book.xml");
// 获取根节点
Element root = doc.getRootElement();
// 获取第一个书节点
Element e_1 = root.element("书");
// 删除属性--方式1
e_1.remove(e_1.attribute("version1"));
// 删除属性--方式2
e_1.addAttribute("version2", null);
// 重新写入文件
writeToXml(doc, "src/book.xml");
}
/**
* 功能:获取document对象 返回值类型:Document 参数列表:String xmlPath
*/
private static Document getDoc(String xmlPath) {
Document dom = null;
try {
SAXReader reader = new SAXReader();
dom = reader.read(new File(xmlPath));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
return dom;
}
/**
* 功能:将修改后的xml文件保存 返回值类型:void 参数列表:(Document document,String xmlPath)
*
*/
private static void writeToXml(Document document, String xmlPath)
throws Exception {
// 将更新的document写入到xml中,并加入格式输入器
XMLWriter writer = new XMLWriter(
new FileOutputStream(new File(xmlPath)),
OutputFormat.createPrettyPrint());
writer.write(document);
writer.close();
}
}
1.XML概述
1.1.XML概述
英文全称为Extensible Markup Language,翻译过来为可扩展标记语言。XML技术是W3C组织发布的,目前遵循的是W3C组织于2000发布的XML1.0规范。
1.2.XML作用
1.2.1.为什么要使用XML
现实生活中存在着大量的数据,在这些数据之间往往存在一定的关系,我们希望能在计算机中保存和处理这些数据的同时能够保存和处理他们之间的关系。
XML就是为了解决这样的需求而产生数据存储格式。
1.2.2.XML是如何保存数据的
在XML语言中,它允许用户自定义标签。每一个标签用于描述一段数据;
一个标签可以分为开始标签和结束标签,在开始标签和结束标签之间又可以嵌套其它标签,利用标签间的嵌套关系来保存数据之间的上下级关系;
xml实质上是一段字符串,计算机可以十分方便的对它进行操作,开发人员也可以方便的阅读,因此可以说这是一种对人、对计算机都友好的数据存储格式,所以XML迅速普及,成为了一种非常常见的数据存储格式,在许多应用场景中得到应用。
1.3.XML的应用场景
1.3.1.传输数据
XML本质上是一段字符串,具有跨平台性的特性,因此XML常被用来在不同系统之间进行数据交换。
国家气象局提供的天气预报接口:
xml接口:http://flash.weather.com.cn/wmaps/xml/china.xml
1.3.2.用作配置文件
XML可以在保存数据的同时保存数据之间的关系。利用这一特点,它还经常被用作应用程序的配置文件。
除此之外,properties文件也可以作为应用程序的配置文件,但是properties文件具有一定的局限性,不能存储具有层级关系的数据。
另外,XML还有一些不太常见的应用场景。
1.4.xml文件
XML是一种存储数据的格式,我们可以将遵照这种数据格式写出来的XML数据保存到一个文件中去,并将文件的后缀名设定为.xml,那么这样的保存了XML数据的文件就叫做xml文件。
xml文件是保存XML数据的一种方式,XML数据也可以以其他的方式存在(如在内存中构建XML数据) 不要将XML语言狭隘的理解成xml文件。
1.5.xml校验
浏览器除了内置HTML解析器以外还内置了XML解析器,因此我们可以使用浏览器对XML进行校验。
实验1: 将前文中XML数据使用xml文件保存起来,利用浏览器进行校验
2.XML语法
一个XML文件分为如下几部分内容:
文档声明
元素
属性
注释
特殊字符、CDATA区
处理指令(processing instruction)
2.1.文档声明
2.1.1.文档声明概述
XML的文档声明是用来声明当前XML文档基本属性的,XML解析器将根据文档声明决定如何正确解析一个XML
通常来说一个XML必须包含且只包含一个文档声明
文档声明必须处在XML的第一行,前面不能有其他内容
如果一个XML不包含文档声明则称这样的XML为格式不良好的XML
在许多时候即使不包含文档声明,XML也可以被正常使用,但是这是不符合标准的,存在风险,因此强烈推荐大家在书写XML时写上文档声明。
2.1.2.文档声明的写法(一)
最简单写法:
version 代表当前xml所遵循的xml标准
在第二个问号之前应该有一个空格
注意:问号、引号、空格都必须为英文半角
2.1.3.文档声明的写法(二)
用encoding属性说明文档的字符编码:
encoding 告知解析器使用何种编码解析当前xml文档
encoding默认值为ISO8859-1
解决方案:编码解码码表一致原则
2.1.4.文档声明的写法(三)
用standalone属性说明文档是否独立:
standalone表示当前xml文档是否是一个独立文档,当为yes时表示是一个独立文档,当为no时表示当前文档需要其他文档支持。
2.1.5.文档声明小结
1)文档声明:用来声明xml的基本的属性,解析器根据文档声明决定如何去解析xml
2)xml中必须包含且只能包含一个文档声明,这个文档声明要求必须放置在xml的第一行的位置,前面不能有任何其他内容
3)
version表明当前xml遵循的xml规范,目前为止,就是1.0
encoding用来声明当前文档使用的编码集,解析器在解析xml时将使用这个编码集打开xml文件,要注意,文件保存时使用的编码和encoding属性指定的编码要相同,这样就能保证没有乱码问题。
standalone属性用来声明当前xml是否是一个独立的文档,默认值是yes,如果一个xml需要依赖其它文档而存在,则需要设置这个属性并且把值设置为no
2.2.元素
2.2.1.XML元素概述
一个XML标签就是一个XML元素。
一个XML标签分为开始标签和结束标签,在开始标签和结束标签之间的文本被称为标签体。
包含标签体:www.tarena.com.cn
如果一个不包含标签体也不包含其他元素,那么可以将开始标签和结束标签合并,这样的标签称为自闭标签。
不含标签体及其他元素:可以简写为自闭标签:
一个标签中也可以嵌套若干子标签。但所有标签必须合理的嵌套,绝对不允许交叉嵌套 ,例如:
welcome to www.tarena.com.cn
welcome to www.tarena.com.cn
welcome to www.tarena.com.cn
welcome to www.tarena.com.cn
格式良好的XML文档必须有且仅有一个根标签,其它标签都是这个根标签的子孙标签。
反例:
www.tarena.com.cn
www.tarena.com
对于XML标签中出现的所有空格和换行,XML解析程序都会当作标签内容进行处理。例如:下面两段内容的意义是不一样的。
由于在XML中,空格和换行都作为原始内容被处理,所以,在编写XML文件时,使用换行和缩进等方式来让原文件中的内容清晰可读的“良好”书写习惯可能要被迫改变。
2.2.2.XML元素命名规范
区分大小写,例如,和
是两个不同的标记。
不能以数字或标点符号开头。
不能以xml(或XML、或Xml 等)开头。
不能包含空格。
名称中间不能包含冒号(:)。
2.3.属性
一个标签可以有多个属性,每个属性都有它自己的名称和取值,例如:
属性值一定要用双引号(")或单引号(')引起来
定义属性名必须遵循与元素相同的命名规范
2.4.注释
Xml文件中的注释采用:“” 格式。
注释不能出现在文档声明之前
注释不能嵌套,例如:
……
-->
2.5.转义字符
2.5.1.转义字符
需求:将name标签中的名字用尖括号(<>)包起来并显示。
实验:将上段XML文本保存在浏览器中显示。
< <
> >
& &
" "
' '
对于一些单个字符,若想显示其原始样式,也可以使用转义的形式予以处理。
3.XML约束
3.1.XML约束概述
什么是XML约束?
在xml技术里,可以编写一个文档来约束一个xml文档的写法,这称之为XML约束。
为什么要使用XML约束?
例如:我们从网上下载了一个开源框架,这个开源框架是使用XML作为配置文件的,这时候框架的设计者就需要约束我们配置文件的写法。
XML约束的作用
约束xml文档的写法
对xml进行校验
常见的XML约束技术
XML DTD
XML Schema
4.XML编程
4.1.XML的两种解析方式
4.1.1.两种解析方式概述
dom解析:
(1)是 W3C 组织推荐的处理 XML 的一种方式。
(2)将整个XML文档使用类似树的结构保存在内存中,再对其进行操作。
(3)可以方便的对xml进行增删该查操作
(4)需要等到XML完全加载进内存才可以进行操作
(5)耗费内存,当解析超大的XML时慎用。
sax解析:
(1)sax (Simple API for XML) 不是官方标准,但它是 XML 社区事实上的标准,几乎所有的 XML 解析器都支持它。
(2)逐行扫描XML文档,当遇到标签时触发解析处理器,采用事件处理的方式解析xml
(3)在读取文档的同时即可对xml进行处理,不必等到文档加载结束,相对快捷
(4)不需要加载进内存,因此不存在占用内存的问题,可以解析超大XML
(5)只能用来读取XML中数据,无法进行增删改
4.1.2.dom解析
DOM: Document Object Model 文档对象模型。
在应用程序中,基于DOM的XML解析器将一个XML文档转换成QQ一个对象模型的集合(通常称DOM树),应用程序通过对这个对象模型的操作,来实现对XML文档数据的操作。
通过DOM接口,应用程序可以在任何时候访问XML文档中的任何一部分数据,因此,这种利用DOM接口的机制也被称作随机访问机制。
DOM树所提供的随机访问方式给应用程序的开发带来了很大的灵活性,它可以任意地控制整个XML文档中的内容。
然而,由于DOM解析器把整个XML文档转化成DOM树放在了内存中,因此,当文档比较大或结构比较复杂时,对内存的需求就比较高。
而且,对于结构复杂的树的遍历也是一项耗时的操作。
所以,DOM解析器对机器性能的要求比较高,实现效率不十分理想。
由于DOM解析器所采用的树结构的思想与XML文档的结构相吻合,同时鉴于随机访问所带来的方便,因此,DOM解析器还是有很广泛的应用价值的。
4.1.3.sax解析
SAX的全称是Simple APIs for XML,也即XML简单应用程序接口。
与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式。
当使用SAX解析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口。
优势:
(1)然而,由于SAX解析器实现简单,对内存要求比较低,(SAX不必将整个XML文档加载到内存当中,所以它占据内存要比DOM小), 因此实现效率比较高。
对于大型的XML文档来说,通常会用SAX而不是DOM。
(2)并且对于那些只需要访问XML文档中的数据而不对文档进行更改的应用程序来说,SAX解析器更为合适。
局限性:
(1) SAX解析器在对XML文档进行分析时,触发了一系列的事件,由于事件触发本身是有时序性的,因此,SAX提供的是一种顺序访问机制,对于已经分析过的部分,不能再倒回去重新处理。
即,一旦经过了某个元素,我们没有办法返回去再去访问它。
(2)SAX解析器只做了一些简单的工作,大部分工作还要由应用程序自己去做。
也就是说,SAX解析器在实现时,只是顺序地检查XML文档中的字节流,判断当前字节是XML语法中的哪一部分、是否符合XML语法,然后再触发相应的事件,而事件处理函数本身则要由应用程序自己来实现。
同DOM解析器相比,SAX解析器缺乏灵活性。
4.1.4.xml解析开发包
Jaxp(sun,j2se)、dom4j(dom4j)
4.2.Dom4j解析
4.2.1.Dom4j简介
Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。
Dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使 用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j。
使用Dom4j开发,需下载dom4j相应的jar文件。
4.2.2.Dom4j继承结构
4.2.3.DOM4j解析xml文档
创建解析器:
SAXReader reader = new SAXReader();
利用解析器读入xml文档:
Document document = reader.read(new File("input.xml"));
获取文档的根节点:
Element root = document.getRootElement();
常用的操作节点的方法:
(1)取得某个节点的子节点.
Element element =ele.element(“书名");
List elementList =ele.elements(“书名");
List elementList =ele.elements();
(2)获取节点的名字
node.getName();
(3)设置节点的名字
node.setName(String newName);
(4)取得节点的文字(标签体)
String text=node.getText()
(5)设置节点的文字(标签体)
node.setText("aaa");
(6)添加子节点.
ele.add(Element e);
ele.addElement("age");
(7)删除子节点节点.
parentElm.remove(childElm);
(8)获取节点类型
node.getNodeType() ;
(9)获取父节点
node.getParent();
(10)取得某节点对象的某属性
Attribute attr= ele.attribute("aaa");
Attribute attr= ele.attribute(0);
List list = ele.attributes();
String value = ele.attributeValue("aaa");
Iterator it = ele.attributeIterator();
(11)设置某节点的属性
ele.add(Attribute attr);
ele.addAttribute(name, value);
ele.setAttributes(List attrs);
(12)删除某属性
ele.remove(attribute);
(13)在指定位置插入节点
a)得到插入位置的节点列表(list)
b)调用list.add(index,elemnent),由index决定element的插入位置。
Element元素可以通过DocumentHelper对象得到。示例代码:
Element aaa = DocumentHelper.createElement("aaa");
aaa.setText("aaa");
List list = root.element("书").elements();
list.add(1, aaa);
(14)取得属性的名、值
String name = attribute.getName();
String value = attribute.getValue();
(15)设置某属性的名、值
attribute.setName();
attribute.setValue();
4.2.4.DOM4j将字符串和XML的转换
1.将字符串转化为XML
String text = " sitinspring ";
Document document = DocumentHelper.parseText(text);
2.将文档或节点的XML转化为字符串.
String xmlStr = node.asXML();
4.2.5.DOM4j将文档写入XML文件
方式一:(推荐)
利用XMLWriter写出Node:
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"));
writer.write(node);
writer.close();
注意:使用这种方式输出时,XMLWriter首先会将内存中的docuemnt翻译成UTF-8格式的document,在进行输出,这时有可能出现乱码问题。
可以使用OutputFormat 指定XMLWriter转换的编码为其他编码。
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("GBK");
XMLWriter writer = new XMLWriter(newFileWriter("output.xml"),format);
Writer使用的编码集与文档载入内存时使用的编码集不同导致乱码,使用字节流或自己封装指定编码的字符流即可。参照上文ppt。
方式二:(不推荐)
调用Node提供的write(Writer writer) 方法,使用默认方式将节点输出到流中:
node.write(new FileWriter("book.xml"));
乱码问题:Dom4j在将文档载入内存时使用的是文档声明中encoding属性声明的编码集进行编码,如果在此时使用的writer的内部编码集与最初载入内存时使用的编码集不同则会出现乱码问题。
FileWriter默认使用操作系统本地码表即gb2312编码,并且无法更改。
此时可以使用OutputStreamWriter(FileOutputStream("filePath"),"utf-8");的方式自己封装一个指定码表的Writer使用,从而解决乱码问题。
4.2.6.DOM4j-DocumentHelper
DocumentHelper中常用的方法:
createDocument();
createDocument(Element rootEle
createAttribute(Element owner, String name, String value));
createElement(String name);
Docuemnt parseText(String text);
4.2.7.DOM4j-XPath
参看XPath文档