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();
}
}
}