DOM解析原理:一次性把xml文档加载成Document树,通过Document对象得到节点对象,通过节点对象访问xml文档内容(标签,属性,文本,注释)。
缺点:不适合读取大容量xml文件,导致内存溢出。
xml对象的一些方法:
节点:
Iterator Element.nodeIterator(); //获取当前标签节点下的所有子节点
标签:
Element Document.getRootElement(); //获取xml文档的根标签
Element ELement.element("标签名") //指定名称的第一个子标签
Iterator Element.elementIterator("标签名");// 指定名称的所有子标签
List Element.elements(); //获取所有子标签
属性:
String Element.attributeValue("属性名") //获取指定名称的属性值
Attribute Element.attribute("属性名");//获取指定名称的属性对象
Attribute.getName() //获取属性名称
Attibute.getValue() //获取属性值
List Element.attributes(); //获取所有属性对象
Iterator Element.attibuteIterator(); //获取所有属性对象
文本:
Element.getText(); //获取当前标签的文本
Element.setText(); //设置当前标签的文本
Element.elementText("标签名") //获取当前标签的指定名称的子标签的文本内容
xml读取(查)
public static void main(String[] args) throws Exception{
List list = new ArrayList();
//获得xml文件
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("./src/contact.xml"));
//获得联系人xml的根标签
Iterator it = doc.getRootElement().elementIterator("contact");
while(it.hasNext()){
Element elem = it.next();
//遍历Contact,并创建联系人对象且赋值
Contact contact = new Contact();
contact.setId(elem.attributeValue("id"));
contact.setName(elem.elementText("name"));
contact.setPhone(elem.elementText("phone"));
contact.setEmail(elem.elementText("email"));
list.add(contact);
}
//遍历打印
for (Contact contact : list) {
System.out.println(contact);
}
}
xml的增删改
1 写出内容到xml文档
XMLWriter writer = new XMLWriter(OutputStream, OutputForamt)
wirter.write(Document);
2 修改xml文档的API
增加:
DocumentHelper.createDocument() 增加文档
addElement("名称") 增加标签
addAttribute("名称",“值”) 增加属性
修改:
Attribute.setValue("值") 修改属性值
Element.addAtribute("同名的属性名","值") 修改同名的属性值
Element.setText("内容") 修改文本内容
删除
Element.detach(); 删除标签
Attribute.detach(); 删除属性
public void fun() throws Exception{
//1.创建doc
//2.添加标签,属性
//3.写xml
//4.修改
//创建doc并写xml
//创建Document对象
// Document doc = DocumentHelper.createDocument();
//获得根标签
// Element rootElem = doc.addElement("students");
//添加数据
// addStudent(rootElem,"1","张三","男","计算机1班","中山东区");
// addStudent(rootElem,"2","李四","女","计算机2班","广州");
// addStudent(rootElem,"3","傻逼","男","计算机3班","深圳");
//修改id为2的学生的名字为"莉莉"
//获得已经存在的xml文件
// SAXReader reader = new SAXReader();
// Document doc= reader.read("E:/student.xml");
//
// Element rootElem = doc.getRootElement();
// List stuElems= rootElem.elements();
//找到id为2的student标签
// for (Object object : stuElems) {
// Element stuElem = (Element)object;
// //获得student标签的属性id
// if(stuElem.attribute("id").getValue().equals("2")){
//修改student标签下的name标签的文本
// stuElem.element("name").setText("莉莉");
// }
// }
//删除id为2的学生
//获得已经存在的xml文件
SAXReader reader = new SAXReader();
Document doc= reader.read("E:/student.xml");
Element rootElem = doc.getRootElement();
List stuElems= rootElem.elements();
//找到id为2的student标签
for (Object object : stuElems) {
Element stuElem = (Element)object;
//找到id为2的student标签
if(stuElem.attribute("id").getValue().equals("2")){
//将id为2的学生标签删除
stuElem.detach();
}
}
//获得漂亮格式的OutputFormat对象
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
//用XMLWriter写xml文件
XMLWriter writer = new XMLWriter(new FileOutputStream("E:/student.xml"),format);
//调用wirte()方法就能够写xml
writer.write(doc);
//记得关流
writer.close();
}
public void addStudent(Element elem,String id,String name,String gender,String grade,String address){
Element stu = elem.addElement("student");
stu.addAttribute("id", id);
Element nameElem = stu.addElement("name");
nameElem.setText(name);
stu.addElement("gender").setText(gender);
stu.addElement("grade").setText(grade);
stu.addElement("address").setText(address);
}
用于快速获取所需的节点对象
使用xpath方法
List selectNodes("xpath表达式"); 查询多个节点对象
Node selectSingleNode("xpath表达式"); 查询一个节点对象
3.4 xPath语法
/ 绝对路径 表示从xml的根位置开始或子元素(一个层次结构)
// 相对路径 表示不分任何层次结构的选择元素。
* 通配符 表示匹配所有元素
[] 条件 表示选择什么条件下的元素
@ 属性 表示选择属性节点
and 关系 表示条件的与关系(等价于&&)
text() 文本 表示选择文本内容
1.创建SAXParser对象
SAXParser parser=SAXParserFactory.newInstance().newSAXParser();
2.调用parse方法
parser.parse(new File("./src/contact.xml"), new MyDefaultHandler());
[一个类继承class 类名(extends DefaultHandler) 在调用是创建传进去
DefaultHandler类的API:
void startDocument() : 在读到文档开始时调用
void endDocument() :在读到文档结束时调用
void startElement(String uri, String localName, String qName, Attributes attributes) :读到开始标签时调用
void endElement(String uri, String localName, String qName) :读到结束标签时调用
void characters(char[] ch, int start, int length) : 读到文本内容时调用
============DOM解析 vs SAX解析 ========
DOM解析 SAX解析
原理: 一次性加载xml文档,不适合大容量的文件读取 原理: 加载一点,读取一点,处理一点。适合大容量文件的读取
DOM解析可以任意进行增删改成 SAX解析只能读取
DOM解析任意读取任何位置的数据,甚至往回读 SAX解析只能从上往下,按顺序读取,不能往回读
DOM解析面向对象的编程方法(Node,Element,Attribute) SAX解析基于事件的编程方法
1)导入dtd方式
内部导入
]>
外部导入
本地文件系统:
公共的外部导入:
2)DTD语法
约束标签
或
类别:
空标签: EMPTY。 表示元素一定是空元素。
普通字符串: (#PCDATA)。表示元素的内容一定是普通字符串(不能含有子标签)。
任何内容: ANY。表示元素的内容可以是任意内容(包括子标签)
(元素内容):
顺序问题:
: 按顺序出现子标签
次数问题:
标签 : 必须且只出现1次。
标签+ : 至少出现1次
标签* : 0或n次。
标签? : 0或1次。
约束属性
默认值:
#REQUIRED 属性值是必需的
#IMPLIED 属性不是必需的
#FIXED value 属性不是必须的,但属性值是固定的
属性类型:控制属性值的
CDATA :表示普通字符串
(en1|en2|..): 表示一定是任选其中的一个值
ID:表示在一个xml文档中该属性值必须唯一。值不能以数字开头