SAXParser解析XML文件
我在之前的一篇文《用dom4j操作xml文件》里曾介绍了XML文件,以及用dom4j操作xml文件。其实,java有个扩展包(javax.xml)里也提供了解析xml的方法。我接下来通过案例予以介绍。
首先,定义xml文件内的元素规则(user.xsd):
<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.itszt2.com" xmlns="http://www.itszt2.com"> <xs:element name="用户" type="type_user"></xs:element> <xs:complexType name="type_user"> <xs:sequence> <xs:element name="姓名" type="type_xm"></xs:element> <xs:element name="年龄" type="type_nl"></xs:element> <xs:element name="性别" type="type_xb" minOccurs="1" maxOccurs="999999999"></xs:element> <xs:element name="工资" type="type_gz"> </xs:element> <xs:element name="出生日期" type="xs:date"></xs:element> <xs:element name="爱好" type="type_hbs"></xs:element> </xs:sequence> </xs:complexType> <!-- 定义姓名的类型 --> <xs:simpleType name="type_xm"> <xs:restriction base="xs:string"> <xs:pattern value="\w{2,10}"/> </xs:restriction> </xs:simpleType> <!-- 定义年龄的类型 --> <xs:simpleType name="type_nl"> <xs:restriction base="xs:integer"> <xs:minInclusive value="0"></xs:minInclusive> <xs:maxInclusive value="100"></xs:maxInclusive> </xs:restriction> </xs:simpleType> <!-- 定义性别类型 --> <xs:simpleType name="type_xb"> <xs:restriction base="xs:string"> <xs:enumeration value="男"/> <xs:enumeration value="女"/> </xs:restriction> </xs:simpleType> <!-- 定义工资属性;复杂类型内设置内容类型,以及属性 --> <xs:complexType name="type_gz"> <xs:simpleContent> <xs:extension base='xs:decimal'> <xs:attribute name='单位' type='xs:string' use="required" default="元" /> </xs:extension> </xs:simpleContent> </xs:complexType> <!--定义爱好类型--> <xs:simpleType name="type_hbs"> <xs:restriction base="xs:string"></xs:restriction> </xs:simpleType> </xs:schema>
接着,写一个xml文件(test1.xml):
<?xml version="1.0"?> <用户 xmlns="http://www.itszt2.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.itszt2.com user.xsd"> <姓名>王二</姓名> <年龄>20</年龄> <性别>男</性别> <工资 单位="元">123.45</工资> <出生日期>1999-10-10</出生日期> <爱好>爬山</爱好> </用户>
再写个实体类User,使得从xml文件读取信息后,相应地生成一个User对象:
package com.itszt; import java.util.List; /** * 实体类 */ public class User { private String username; private String usersex; private String userdate; private String usersalary; private int userage; private String userhbs; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getUsersex() { return usersex; } public void setUsersex(String usersex) { this.usersex = usersex; } public String getUserdate() { return userdate; } public void setUserdate(String userdate) { this.userdate = userdate; } public String getUsersalary() { return usersalary; } public void setUsersalary(String usersalary) { this.usersalary = usersalary; } public int getUserage() { return userage; } public void setUserage(int userage) { this.userage = userage; } public String getUserhbs() { return userhbs; } public void setUserhbs(String userhbs) { this.userhbs = userhbs; } @Override public String toString() { return "User [username=" + username + ", usersex=" + usersex + ", userdate=" + userdate + ", usersalary=" + usersalary + ", userage=" + userage + ", userhbs=" + userhbs + "]"; } }
写一个servlet,使得前台页面点击链接,访问该servlet,从而触发读取xml文件,以及对象操作:
package com.itszt; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * 读取xml文件 */ @WebServlet(name = "SAX2Servlet",urlPatterns = "/SAX2Servlet") public class SAX2Servlet extends HttpServlet { private ThreadLocal<String> qNameNow=new ThreadLocal<String>(); private ThreadLocal<User> userNow=new ThreadLocal<User>(); protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try{ //工厂模式,获取xml解析器,再从xml文件中读取流 SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); XMLReader reader = parser.getXMLReader(); reader.setContentHandler(new DefaultHandler(){ @Override public void startDocument() throws SAXException { super.startDocument(); System.out.println("开始解析整个xml文档"); } @Override public void endDocument() throws SAXException { super.endDocument(); System.out.println("结束解析整个xml文档"); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); System.out.println("开始解析元素:"+qName); if("用户".equals(qName)){ userNow.set(new User()); } qNameNow.set(qName); if("工资".equals(qName)){ String dw = attributes.getValue("单位"); System.out.println("dw = " + dw); String num = attributes.getValue("num"); System.out.println("num = " + num); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); System.out.println("结束解析标签: " + qName); if("用户".equals(qName)){ System.out.println("解析完毕,获取到user:"+userNow.get()); } //结束某个标签元素的解析后,对qNameNow进行重置 qNameNow.set(""); } @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); String value=new String(ch,start,length); System.out.println("找到一个值: "+value); if("姓名".equals(qNameNow.get())){ userNow.get().setUsername(value); } if("年龄".equals(qNameNow.get())){ userNow.get().setUserage(Integer.parseInt(value)); } if("性别".equals(qNameNow.get())){ userNow.get().setUsersex(value); } if("出生日期".equals(qNameNow.get())){ userNow.get().setUserdate(value); } if("工资".equals(qNameNow.get().toString())){ userNow.get().setUsersalary(value); } if("爱好".equals(qNameNow.get())){ userNow.get().setUserhbs(value); } } }); //发起解析 String xmlPath = request.getServletContext().getRealPath("/test3/test1.xml"); reader.parse(xmlPath); }catch (Exception e){ e.printStackTrace(); } } }