xml的创建,解析
- 1. 什么是xml文件
- 1.1 什么是xml文件
- 1.2 解析xml的方式,优缺点
- 2. 使用dom操作xml文件
- 2.1 使用dom创建xml文件
- 2.2 使用dom解析xml文件
- 2.3 使用dom对xml文件增删改
- 3. 使用SAX解析xml文件
- 4. 使用DOM4J操作xml文件
- 4.1 使用DOM4J创建xml文件
- 4.2 使用DOM4J解析xml文件
1. 什么是xml文件
1.1 什么是xml文件
可标记的扩展语言(文本文件) 类似html文件,xml标签有头有尾部。可读性高。
xml的实际用途:
1.数据存储和传递的媒介
2.作为配置文件
- XML中的相关概念(叫法)
- 按级别来分
a:根节点(有且只能有一个)
b:父节点
c:子节点
d:兄弟节点 - 按类型来分
a:元素节点
b:属性节点
c:文本节点 - 如下就是一个xml文件
1.2 解析xml的方式,优缺点
- 使用Java操作xml文件,有DOM和SAX
- 优缺点比较
DOM的特点:
- 在操作xml文档时需要将整个文档加载到内存,操作灵活方便,但对内存消耗过大
- 功能齐全,能创建/解析xml文档,能删除/添加/修改节点信息
SAX的特点:(事件驱动模式) - 在操作xml文档时是从上到下来加载xml,操作没有dom那么灵活,但内存消耗较dom要小
- 功能没有dom齐全,只能创建/解析xml
dom4j:
- 集dom和sax的特点于一起
- 功能更强大
2. 使用dom操作xml文件
2.1 使用dom创建xml文件
- 下面创建了person.xml 和 stu.xml
- 直接用排版印刷怼 和 封装好排版和印刷
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 onestatic 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); // 解析xmlreturn 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 difficultiesstatic 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();// 解析xmlDocument 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获取结点的其它方式
Element root = doc.getDocumentElement();root.getFirstChild();//获得当前节点第一个子节点root.getLastChild();//获得当前节点最后一个子节点root.getNextSibling();//获得当前节点下一个兄弟节点root.getPreviousSibling();//获得当前节点上一个兄弟节点root.getParentNode();//获得当前节点父节点
2.2 使用dom解析xml文件
- 对books.xml解析
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#
*/
2.3 使用dom对xml文件增删改
- 如图
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 blocke.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 blocke.printStackTrace();}}
3. 使用SAX解析xml文件
- 继承DefaultHander类
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;}@Overridepublic void startDocument() throws SAXException {System.out.println("解析根节点");}@Overridepublic void endDocument() throws SAXException {System.out.println("根结点解析结束");}@Overridepublic 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);}@Overridepublic 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);}
}
- person实体
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 + "]";}}
- sax解析
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解析xmlSAXParserFactory 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]]*/
4. 使用DOM4J操作xml文件
4.1 使用DOM4J创建xml文件
-
创建如图所示的xml
-
使用dom4j前提
- coding…
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();}}}}
4.2 使用DOM4J解析xml文件
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();}// 根节点studentsElement root = doc.getRootElement();List<Element> list = root.elements();// 拿到每个学生结点的名字和姓名for (Element stu : list) {// stu.element("name"); 拿到name结点// 获取属性值idSystem.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解析原理。