可标记的扩展语言(文本文件) 类似html文件,xml标签有头有尾部。可读性高。
xml的实际用途:
1.数据存储和传递的媒介
2.作为配置文件
DOM的特点:
dom4j:
package test;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
*
* @author echo lovely
*
* dom模式下的
* xml文件的解析,读取,增删改
*
* 优缺点:
* 1. 消耗内存大,把整个xml读到内存,适合数据少的读取
* 2. 灵活,可对整个xml文档进行操作,操作父子,兄弟,第一个,最后一个结点
*
* 排版:
* DocumentBuliderFactory BuilderFactory Document
*
* 印刷:
* TransformerFactory Transformer transfome
* */
public class DocumentXMLNode {
public static void main(String[] args) throws Exception {
// createNew();
// parserXML();
// DOMAddXML();
// DOMUpdateXML();
DOMDeleteXML();
}
// one by one
static void createXML() throws Exception {
// 创建一个排版工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 创建一个排版机器
DocumentBuilder db = factory.newDocumentBuilder();
// 准备好空白文档,准备排版
Document doc = db.newDocument();
// 创建根节点
Element root = doc.createElement("Student");
// 把根结点挂载到文档中
doc.appendChild(root);
for (int i = 0; i < 3; i ++) {
// 创建stu结点
Element stu = doc.createElement("stu" + (i + 1));
// 把元素结点添加到stu结点下
root.appendChild(stu);
// 设置element的属性
stu.setAttribute("id",(i + 1) + "");
// 创建学生的姓名结点
Element name = doc.createElement("name");
name.setTextContent("小明" + i);
stu.appendChild(name);
// 学生的年龄结点
Element age = doc.createElement("age");
age.setTextContent("" + (18 + i));
stu.appendChild(age);
}
// 印刷
// 创建印刷工场
TransformerFactory tff = TransformerFactory.newInstance();
// 印刷机器
Transformer tf = tff.newTransformer();
// 开始印刷
// 创建xml数据源
DOMSource source = new DOMSource(doc);
// 确定输出位置
StreamResult res = new StreamResult("stu.xml");
tf.transform(source, res);
}
// 排版 or 解析
static Document DOMComposing(String path) throws Exception {
// 排版工场
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 排版机器
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = null;
// 空白文档,准备排版
if (path == "" || path == null)
doc = db.newDocument();
else
doc = db.parse(path); // 解析xml
return doc;
}
/**
* @param doc 排版文档
* @param xml文件输出路径
* @throws Exception
*/
static void DOMPrinting(Document doc, String outputPath) throws Exception {
// 排版工场
TransformerFactory tff = TransformerFactory.newInstance();
// 排版机器
Transformer tf = tff.newTransformer();
// 数据源
DOMSource xmlSource = new DOMSource(doc);
// 输出地址,开始排版 file:/// 中文路径乱码
StreamResult res = new StreamResult(new File(outputPath));
tf.transform(xmlSource, res);
}
// hide difficulties
static void createNew() {
try {
Document doc = DOMComposing("");
Element root = doc.createElement("person");
doc.appendChild(root);
for (int i = 0; i < 3; i ++) {
Element teacher = doc.createElement("teacher");
teacher.setAttribute("id", "" + (i + 1));
root.appendChild(teacher);
Element name = doc.createElement("name");
// 设置name结点的文本内容
name.setTextContent("cici" + (i + 1));
Element age = doc.createElement("age");
age.setTextContent((24 + i) + "");
// 把姓名和年龄添加到teacher结点
teacher.appendChild(name);
teacher.appendChild(age);
}
DOMPrinting(doc, "person.xml");
} catch (Exception e) {
e.printStackTrace();
}
}
static void parserXML() throws Exception {
// 排版解析
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
// 解析xml
Document doc = db.parse(new File("stu.xml"));
// Element root = (Element) doc.getFirstChild();
Element root = doc.getDocumentElement();
NodeList nodes = root.getChildNodes();
System.out.println(nodes.item(0));
for (int i = 0; i < nodes.getLength(); i++) {
Element stu = (Element) nodes.item(i);
String text = nodes.item(i).getFirstChild().getTextContent();
System.out.println(stu.getAttribute("id") + "\t" + text);
}
}
}
Element root = doc.getDocumentElement();
root.getFirstChild();//获得当前节点第一个子节点
root.getLastChild();//获得当前节点最后一个子节点
root.getNextSibling();//获得当前节点下一个兄弟节点
root.getPreviousSibling();//获得当前节点上一个兄弟节点
root.getParentNode();//获得当前节点父节点
static void domParse() {
Document doc = docComposing("books.xml");
Element root = (Element) doc.getFirstChild();
NodeList list = root.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Element book = (Element) list.item(i);
System.out.println(book.getAttribute("id") + "\t" + book.getTextContent());
}
}
/**
1001 java
1002 c#
*/
static void DOMAddXML() {
try {
Document doc = DOMComposing("person.xml");
// 得到第二个name结点下面的第一个结点
Element name = (Element) doc.getFirstChild().getFirstChild().getNextSibling().getFirstChild();
// System.out.println(name.getTextContent() + "--" + name.getAttribute("id"));
// 创建gender结点
Element gender = doc.createElement("gender");
name.getParentNode().appendChild(gender);
gender.setTextContent("female");
DOMPrinting(doc, "person.xml");
} catch (Exception e) {
e.printStackTrace();
}
}
static void DOMUpdateXML() {
try {
Document doc = DOMComposing("person.xml");
doc.getDocumentElement().getLastChild().setTextContent("null");
DOMPrinting(doc, "person.xml");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static void DOMDeleteXML() {
try {
Document doc = DOMComposing("person.xml");
Element beRemoved = (Element) doc.getDocumentElement().getLastChild();
beRemoved.getParentNode().removeChild(beRemoved);
DOMPrinting(doc, "person.xml");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
package test;
import java.util.ArrayList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import entity.Person;
public class MyDefaultHandler extends DefaultHandler {
private ArrayList<Person> list;
private Person p;
private String tagName;
// 重写
public MyDefaultHandler(ArrayList<Person> list) {
this.list = list;
}
@Override
public void startDocument() throws SAXException {
System.out.println("解析根节点");
}
@Override
public void endDocument() throws SAXException {
System.out.println("根结点解析结束");
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
this.tagName = qName; // 标记元素结点的值
if ("teacher".equals(qName)) { // 开始解析第一个teacher结点 准备进行数据封装
p = new Person(); // 有几个结点便会产生几个person 对象
System.out.println(p);
list.add(p);
p.setId(Integer.parseInt(attributes.getValue("id")));
}
System.out.println("元素结点解析开始 " + qName);
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// System.out.println("元素结点解析结束... ");
}
// 文本结点值
public void characters(char[] ch, int start, int length)
throws SAXException {
String value = new String(ch, start, length);
if ("name".equals(tagName)) {
p.setName(value);
} else if ("age".equals(tagName)) {
p.setAge(Integer.parseInt(value));
} else if ("gender".equals(tagName)) {
p.setGender(value);
}
System.out.println("文本元素值 " + value);
}
}
package entity;
public class Person {
// 用于存储xml集合保存的数据
private Integer id;
private Integer age;
private String name;
private String gender;
public Person() {}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Person [id=" + id + ", age=" + age + ", name=" + name
+ ", gender=" + gender + "]";
}
}
package test;
import java.io.IOException;
import java.util.ArrayList;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import entity.Person;
public class SAXParseXML {
public static void main(String[] args) {
// 使用sax解析xml
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = null;
ArrayList<Person> list = new ArrayList<Person>();
try {
sp = spf.newSAXParser();
sp.parse("person.xml", new MyDefaultHandler(list));
} catch (ParserConfigurationException | SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(list);
}
}
/**
*[Person [id=1, age=24, name=cici1, gender=female],
Person [id=2, age=25, name=cici2, gender=female],
Person [id=3, age=26, name=cici3, gender=null]]
*/
package test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.XMLWriter;
public class Dom4jCreateXML {
public static void main(String[] args) {
// xml文档对象
Document doc = DocumentHelper.createDocument();
// 根节点对象
Element root = doc.addElement("Students");
// 第一个学生结点
Element stu1 = root.addElement("student");
stu1.addAttribute("id", "1");
// 添加姓名结点
stu1.addElement("name").addText("rye");
// 添加性别结点
stu1.addElement("gender").addText("female");
// 可以在创建学生结点的同时添加id属性
Element stu2 = root.addElement("student").addAttribute("id", 2 + "");
stu2.addElement("name").addText("jack");
stu2.addElement("gender").addText("male");
Element stu3 = root.addElement("student").addAttribute("id", 3 + "");
stu3.addElement("name").addText("rose");
stu3.addElement("gender").addText("male");
// 利用XMLWriter把内存中的xml 写入文件
XMLWriter w = null;
try {
w = new XMLWriter(new OutputStreamWriter(new FileOutputStream("student.xml"), "utf-8"));
w.write(doc);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (w != null)
w.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package test;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
public class DOM4jParseXML {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
// SAXReader 读取xml文件
SAXReader reader = new SAXReader();
Document doc = null;
try {
doc = reader.read("student.xml");
} catch (DocumentException e) {
e.printStackTrace();
}
// 根节点students
Element root = doc.getRootElement();
List<Element> list = root.elements();
// 拿到每个学生结点的名字和姓名
for (Element stu : list) {
// stu.element("name"); 拿到name结点
// 获取属性值id
System.out.println(stu.attributeValue("id"));
System.out.println(stu.elementText("name") + "\t" + stu.elementText("gender"));
}
// 记住! 语法有 有斜杠 必须导入jaxen-1.1.6.jar
List<Element> nameNodes = root.selectNodes("//name");
nameNodes = doc.selectNodes("//student/name");
nameNodes = doc.selectNodes("//student/gender");
for (Element name : nameNodes) {
System.out.println(name.getName() + "\t" + name.getText());
}
// 拿到单个结点
Node stuNode1 = doc.selectSingleNode("//Students/student[@id='1']/name");
System.out.println(stuNode1.getName() + "\t " + stuNode1.getText());
}
}
/**
1
rye female
2
jack male
3
rose male
gender female
gender male
gender male
name rye
*/
最后使用dom4j工具类虽然能给我们简化大量解析xml的代码,但是还是得了解jdk提供的api解析原理。