一 xml的定义方式:
xml的定义方式有dtd和schema两种模式,这两种模式的本质区别是schema是xml模式,而dtd是文档类型定义。
另外schema的可扩展性强,dtd的可扩展性较差;schema支持丰富的数据类型,dtd支持的类型有限;schema支持命名空间,dtd不支持;
二 xml的解析方式:
xml经常用到的解析方式:dom解析和sax解析;
dom解析是把xml文档看做对象,加载到内存中,如果文档较大,系统处理性能下降,适用于小文档解析,适用于随机访问;
sax解析,他是事件驱动的,解析时候不需要加载整个文档,在解析遇到文档开始和结束,标签的开始和结束时候,会触发事件,对事件使用回调函数来解析,适用于文档的顺序解析。
三 两种解析方式解析实例
(a) dom解析:
1 随机访问xml:
student.xml
<?xml version="1.0" encoding="GB2312" standalone="no"?> <students> <student name="张三"> <age>20</age> <school>北方交大</school> </student> <student name="李四"> <age>21</age> <school>北大</school> </student> <student name="王五"> <age>18</age> <school>清华</school> </student> </students>
XMLTools.java
package com.jx; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class XMLTools { public static void main(String[] args) { List names=new ArrayList(); List ages=new ArrayList(); List schools=new ArrayList(); try { DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance(); DocumentBuilder db=dbf.newDocumentBuilder(); Document d=db.parse("src/student.xml"); NodeList nodeList=d.getElementsByTagName("student"); for(int i=0;i<nodeList.getLength();i++){ Node node=nodeList.item(i); Element element=(Element)node; names.add(element.getAttribute("name")); } NodeList nodeList1=d.getElementsByTagName("age"); for(int i=0;i<nodeList1.getLength();i++){ Node node=nodeList1.item(i); Element element=(Element)node; ages.add(element.getFirstChild().getNodeValue()); } NodeList nodeList2=d.getElementsByTagName("school"); for(int i=0;i<nodeList2.getLength();i++){ Node node=nodeList2.item(i); Element element=(Element)node; schools.add(element.getFirstChild().getNodeValue()); } for(int i=0;i<names.size();i++){ System.out.println((String)names.get(i)+"-"+(String)ages.get(i)+"-"+(String)schools.get(i)); } } catch (Exception e) { e.printStackTrace(); } } }
2 增加元素
package com.jx; import java.io.FileOutputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; 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; import org.w3c.dom.Text; public class Add { public static void main(String[] args) { try { DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance(); DocumentBuilder db=dbf.newDocumentBuilder(); Document d=db.parse("src/student.xml"); Element studentElement=d.createElement("student"); studentElement.setAttribute("name","赵六"); Element ageElement=d.createElement("age"); Text ageText=d.createTextNode("22"); Element schoolElement=d.createElement("school"); Text schoolText=d.createTextNode("北京理工大学"); ageElement.appendChild(ageText); schoolElement.appendChild(schoolText); studentElement.appendChild(ageElement); studentElement.appendChild(schoolElement); NodeList nodeList=d.getElementsByTagName("students"); Element students=(Element) nodeList.item(0); students.appendChild(studentElement); System.out.println("添加成功"); //保持XML文件 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource domSource = new DOMSource(d); //设置编码类型 transformer.setOutputProperty(OutputKeys.ENCODING,"gb2312"); StreamResult result = new StreamResult(new FileOutputStream("src/student.xml")); //把DOM树转换为XML文件 transformer.transform(domSource,result); } catch (Exception e) { e.printStackTrace(); } } }
3 修改元素
package com.jx; import java.io.FileOutputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; 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.Node; import org.w3c.dom.NodeList; public class Update { public static void main(String[] args) { try { DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance(); DocumentBuilder db=dbf.newDocumentBuilder(); Document d=db.parse("src/student.xml"); //找到要修改的节点 NodeList nodeList=d.getElementsByTagName("student"); for(int i=0;i<nodeList.getLength();i++){ Element studentElement=(Element) nodeList.item(i); if(studentElement.getAttribute("name").equalsIgnoreCase("赵六")){ studentElement.setAttribute("name","甲"); Node ageNode=studentElement.getFirstChild(); Element ageElement=(Element) ageNode; ageNode.getFirstChild().setNodeValue("20"); Node schoolNode=studentElement.getLastChild(); Element schoolElement=(Element) schoolNode; schoolElement.getFirstChild().setNodeValue("北航"); System.out.println("修改完毕"); } } //保持XML文件 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource domSource = new DOMSource(d); //设置编码类型 transformer.setOutputProperty(OutputKeys.ENCODING,result); } catch (Exception e) { e.printStackTrace(); } } }
4 删除元素
package com.jx; import java.io.FileOutputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; 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; public class Delete { public static void main(String[] args) { try { DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance(); DocumentBuilder db=dbf.newDocumentBuilder(); Document d=db.parse("src/student.xml"); NodeList nodeList=d.getElementsByTagName("student"); for(int i=0;i<nodeList.getLength();i++){ Element element=(Element)nodeList.item(i); if(element.getAttribute("name").equalsIgnoreCase("甲")){ d.getElementsByTagName("students").item(0).removeChild(nodeList.item(i)); System.out.println("移除成功"); } } //保持XML文件 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource domSource = new DOMSource(d); //设置编码类型 transformer.setOutputProperty(OutputKeys.ENCODING,result); } catch (Exception e) { e.printStackTrace(); } } }
(b)sax解析
1 解析含有文本节点的xml
emp.xml;
<?xml version="1.0" encoding="GB2312" standalone="no"?><emps> <emp> <name>张三</name> <age>22</age> </emp> <emp> <name>李四</name> <age>20</age> </emp> </emps>
Emp.java
package com.sax; public class Emp { private String name; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } }
SaxXML.java
package com.sax; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class SaxXML extends DefaultHandler{ private Emp emp; private List<Emp> emps; private String preTag;//记录解析时候的上一个节点名称 public void startDocument() throws SAXException { emps=new ArrayList<Emp>(); } public void startElement(String uri,String localName,String name,Attributes attr) throws SAXException { if ("emp".equals(name)) { emp = new Emp(); } preTag = name;//将正在解析的节点名称赋给preTag } public void endElement(String uri,String name) throws SAXException { if ("emp".equals(name)) { emps.add(emp); } preTag = null; } public void characters(char[] ch,int start,int length) throws SAXException { if (preTag != null) { String data = new String(ch,start,length); if ("name".equals(preTag)) { emp.setName(data); } if ("age".equals(preTag)) { emp.setAge(data); } } } public List<Emp> getEmps(InputStream xmlStream) throws Exception{ SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); SaxXML handler = new SaxXML(); parser.parse(xmlStream,handler); return handler.getEmps(); } public List<Emp> getEmps(){ return emps; } public static void main(String[] args) throws Exception { SaxXML saxXML=new SaxXML(); InputStream inputStream=saxXML.getClass().getClassLoader().getResourceAsStream("emp.xml"); List<Emp> empList=saxXML.getEmps(inputStream); for(Emp e:empList){ System.out.println(e.getName()+":"+e.getAge()); } } }
2 解析含有属性节点的xml
teacher.xml
<?xml version="1.0" encoding="GB2312" standalone="no"?><teachers> <teacher> <name data="李老师"/> <gender data="男"/> </teacher> <teacher> <name data="张老师"/> <gender data="女"/> </teacher> <teacher> <name data="刘老师"/> <gender data="女"/> </teacher> </teachers>
Teacher.java
package com.sax; public class Teacher { private String name; private String gender; 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; } }
SaxXmlTeacher.java
package com.sax; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class SaxXmlTeacher extends DefaultHandler{ private Teacher teacher; private List<Teacher> teachers; private String preTag;//记录解析时候的上一个节点名称 public void startDocument() throws SAXException { teachers=new ArrayList<Teacher>(); } public void startElement(String uri,Attributes attr) throws SAXException { if ("teacher".equals(name)) { teacher=new Teacher(); preTag = name;//将正在解析的节点名称赋给preTag } if ("name".equals(name)) { teacher.setName(attr.getValue("data")); } if ("gender".equals(name)) { teacher.setGender(attr.getValue("data")); } } public void endElement(String uri,String name) throws SAXException { if ("teacher".equals(name)) { teachers.add(teacher); preTag = null; } } public void characters(char[] ch,int length) throws SAXException { } public List<Teacher> getTeachers(InputStream xmlStream) throws Exception{ SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); SaxXmlTeacher handler = new SaxXmlTeacher(); parser.parse(xmlStream,handler); return handler.getTeachers(); } public List<Teacher> getTeachers(){ return teachers; } public static void main(String[] args) throws Exception { SaxXmlTeacher saxXML=new SaxXmlTeacher(); InputStream inputStream=saxXML.getClass().getClassLoader().getResourceAsStream("teacher.xml"); List<Teacher> teachers=saxXML.getTeachers(inputStream); for(Teacher e:teachers){ System.out.println(e.getName()+":"+e.getGender()); } } }
3 解析既含有属性节点又含有文本节点的xml
student.xml
<?xml version="1.0" encoding="GB2312" standalone="no"?><students> <student name="张三"> <age>20</age> <school>北方交大</school> </student> <student name="李四"> <age>21</age> <school>北大</school> </student> <student name="王五"> <age>18</age> <school>清华</school> </student> </students>
Student.java
package com.sax; public class Student { private String name; private String age; private String school; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getSchool() { return school; } public void setSchool(String school) { this.school = school; } }
SaxXmlStudent.java
package com.sax; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class SaxXmlStudent extends DefaultHandler{ private Student student; private List<Student> students; private String preTag;//记录解析时候的上一个节点名称 public void startDocument() throws SAXException { students=new ArrayList<Student>(); } public void startElement(String uri,Attributes attr) throws SAXException { if ("student".equals(name)) { student=new Student(); } preTag = name;//将正在解析的节点名称赋给preTag if ("student".equals(name)) { student.setName(attr.getValue("name")); } } public void characters(char[] ch,int length) throws SAXException { if (preTag != null) { String data = new String(ch,length); if ("school".equals(preTag)) { student.setSchool(data); } if ("age".equals(preTag)) { student.setAge(data); } } } public void endElement(String uri,String name) throws SAXException { if ("student".equals(name)) { students.add(student); } preTag = null; } public List<Student> getStudents(InputStream xmlStream) throws Exception{ SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); SaxXmlStudent handler = new SaxXmlStudent(); parser.parse(xmlStream,handler); return handler.getStudents(); } public List<Student> getStudents(){ return students; } public static void main(String[] args) throws Exception { SaxXmlStudent saxXML=new SaxXmlStudent(); InputStream inputStream=saxXML.getClass().getClassLoader().getResourceAsStream("student.xml"); List<Student> students=saxXML.getStudents(inputStream); for(Student e:students){ System.out.println(e.getName()+"-"+e.getAge()+"-"+e.getSchool()); } } }