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();
        }
    }
}
posted @ 2018-04-28 23:01  奔跑在梦想的道路上  阅读(6071)  评论(0编辑  收藏  举报