xml解析
Dtd约束和Schema约束
DTD的局限性
——DTD不遵循XML的语法,它有自己的一套语法
——DTD数据类型有限,只有PCDATA(可看做字符串)
——DTD不可扩展
Schema的新特性
——Schema基于xml语法
——Schema可以用能处理XML文档的工具来处理
——Schema大大扩充了数据类型,可以自定义数据类型
——Schema支持元素的继承
——Schema支持属性组
一、Dom解析
Dom解析是直接把xml文档加载成Document树,通过访问Document对象来得到节点,通过节点对象来访问xml文档的内容
练习:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <students xmlns="http://www.example.org/s1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/s1 s1.xsd"> <student id="34"> <name></name> <age></age> <gender></gender> </student> <student> <name></name> <age></age> <gender></gender> </student> </students>
<?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/s1" xmlns:tns="http://www.example.org/s1" elementFormDefault="qualified"> <element name="students"> <complexType> <sequence> <element name="student" maxOccurs="2" minOccurs="1"> <complexType> <sequence> <element name="name" type="string" ></element> <element name="age" type="string"></element> <element name="gender" type="string"></element> </sequence> <attribute name="id" type="int"></attribute> </complexType> </element> </sequence> </complexType> </element> </schema>
public class DomTest { public static void main(String[] args) throws Exception { //先得到一个工厂 DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance(); //从工厂里拿到文档创建器 DocumentBuilder db=dbf.newDocumentBuilder(); //开始创建文档 Document dc=db.parse(new File("WebRoot/Test/student.xml")); NodeList list=dc.getElementsByTagName("students"); Node node=list.item(0); System.out.println(node); System.out.println(node.getNodeName()); NodeList list1=node.getChildNodes(); for (int i = 0; i <list1.getLength(); i++) { Node node1=list1.item(i); System.out.println(node1.getNodeName()); } }
public static void main(String[] args) throws Exception { DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance(); DocumentBuilder db=dbf.newDocumentBuilder(); Document doc=db.parse(new File("WebRoot/Test/students.xml")); //得到student 的结点 Node studentNode =doc.getElementsByTagName("student").item(0); Node nameNode =doc.getElementsByTagName("name").item(0); //移除它的子节点 studentNode.removeChild(nameNode); //xml格式化工厂 获取里面的格式化类。 TransformerFactory tff=TransformerFactory.newInstance(); //就可以得到格式化类 Transformer tf=tff.newTransformer(); //创建资源 资源代表 整个文档的资源 //doc 删除之后的xml DOMSource ds=new DOMSource(doc); //代表回写的目录 StreamResult sr=new StreamResult(new File("WebRoot/Test/students.xml")); tf.transform(ds, sr); }
public static void main(String[] args) throws Exception { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(new File("WebRoot/Test/students.xml")); NodeList list = doc.getElementsByTagName("student"); Node node = list.item(0); // 创建结点 Document 这个对象来创建结点 Element addEle = doc.createElement("city"); // 给新创建的这个结点 设置属性 addEle.setAttribute("name", "杭州"); node.appendChild(addEle); TransformerFactory tff = TransformerFactory.newInstance(); // 获取格式化类 Transformer tf = tff.newTransformer(); // 将改变之后的dom文档传入 DOMSource ds = new DOMSource(doc); // 回写的路径 StreamResult sr = new StreamResult( new File("WebRoot/Test/students.xml")); tf.transform(ds, sr); }
二、SAX解析
练习:
public class SAXTest { public static void main(String[] args) throws Exception { //创建解析器工厂对象 SAXParserFactory saxf=SAXParserFactory.newInstance(); //创建解析器对象 SAXParser saxp=saxf.newSAXParser(); //传入路径 saxp.parse(new File("WebRoot/Test/student.xml"),new myHandler() ); } } class myHandler extends DefaultHandler{ @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub System.out.println("开始 解析文档。。。。。"); } @Override public void endDocument() throws SAXException { // TODO Auto-generated method stub System.out.println("结束解析文档"); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // TODO Auto-generated method stub System.out.println("开始解析元素:"+qName); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // TODO Auto-generated method stub System.out.println("结束解析元素"+qName); } @Override public void characters(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub String str=new String(ch, start, length); System.out.println("元素数据"+str); } }
DOM和SAX的不同:
1. DOM是基于内存的,不管文件有多大,都会将所有的内容预先装载到内存中。从而消耗很大的内存空间。而SAX是基于事件的。当某个事件被触发时,才获取相应的XML的部分数据,从而不管XML文件有多大,都只占用了少量的内存空间。
2. DOM可以读取XML也可以向XML文件中插入数据,而SAX却只能对XML进行读取,而不能在文件中插入数据。这也是SAX的一个缺点。
3.SAX的另一个缺点:DOM我们可以指定要访问的元素进行随机访问,而SAX则不行。SAX是从文档开始执行遍历的。并且只能遍历一次。也就是说我们不能随机的访问XML文件,只能从头到尾的将XML文件遍历一次。
三、dom4j
练习:
public static void main(String[] args) throws Exception { SAXReader reader = new SAXReader(); //通过解析器 获取 document 对象 xml 文档 Document document = reader.read(new File("WebRoot/Test/students.xml")); Element eleroot=document.getRootElement(); Element eleStudent =eleroot.element("student"); //创建元素用 整个文档的对象创建 Element elecreate = DocumentHelper.createElement("city"); Attribute att= DocumentHelper.createAttribute(elecreate, "name", "杭州"); elecreate.add(att); eleStudent.add(elecreate); //进行xml 格式 的格式化 OutputFormat out=OutputFormat.createPrettyPrint(); out.setEncoding("utf-8"); //回写的路径 //什么流可以设置编码 ???? // XMLWriter xw=new XMLWriter( // new PrintWriter(new File("WebRoot/Test/students.xml")), // out); XMLWriter xw=new XMLWriter(new OutputStreamWriter(new FileOutputStream("WebRoot/Test/students.xml"),"utf-8"), out); xw.write(document); xw.close(); }