>  기사  >  백엔드 개발  >  Java&Xml 자습서(5) SAX를 사용하여 XML 파일 구문 분석

Java&Xml 자습서(5) SAX를 사용하여 XML 파일 구문 분석

黄舟
黄舟원래의
2017-02-22 14:42:061622검색

Java SAX 구문 분석 메커니즘은 XML 파일을 처리하기 위한 일련의 API를 제공합니다. SAX 구문 분석은 XML 파일의 전체 내용을 한 번에 로드하지 않고 일부를 지속적으로 로드합니다.

javax.xml.parsers.SAXParser 클래스는 이벤트 처리를 사용하여 XML 문서를 구문 분석하는 몇 가지 기능을 제공합니다. 이 클래스는 XMLReader 인터페이스를 구현하고 File, InputStream, SAX InputSource 및 Read XML 문서에서 오버로드된 구문 분석() 메서드를 제공합니다. URI 문자열에서.
실제 XML 구문 분석 작업은 Handler 클래스에 의해 완료됩니다. 이를 위해서는 org.xml.sax.ContentHandler 인터페이스를 구현해야 하는 자체 Handler 클래스를 만들어야 합니다. 이 인터페이스에는 StartDocument, EndDocument, StartElement, EndElement, CharacterData 등과 같은 이벤트가 발생할 때 알림을 받는 콜백 메서드가 포함되어 있습니다.

org.xml.sax.helpers.DefaultHandler은 ContentHandler 인터페이스의 기본 구현을 제공하므로 이 클래스를 상속하여 자체 처리 클래스를 구현할 수 있습니다. 이 클래스를 상속받는 것은 몇 가지 메서드만 구현하면 되기 때문에 현명한 선택입니다. 이 클래스를 상속하면 코드의 단순성과 유지 관리 가능성이 보장됩니다.
다음은 구문 분석하려는 XML 문서입니다.
employees.xml

<?xml version="1.0" encoding="UTF-8"?><Employees>
    <Employee id="1">
        <age>29</age>
        <name>Pankaj</name>
        <gender>Male</gender>
        <role>Java Developer</role>
    </Employee>
    <Employee id="2">
        <age>35</age>
        <name>Lisa</name>
        <gender>Female</gender>
        <role>CEO</role>
    </Employee>
    <Employee id="3">
        <age>40</age>
        <name>Tom</name>
        <gender>Male</gender>
        <role>Manager</role>
    </Employee>
    <Employee id="4">
        <age>25</age>
        <name>Meghna</name>
        <gender>Female</gender>
        <role>Manager</role>
    </Employee></Employees>

이 XML 파일의 내용은 일부 직원 정보를 저장합니다. 각 직원에는 ID 속성과 나이, 이름, 성별 및 역할 필드.
SAX 구문 분석 메커니즘을 사용하여 XML 파일을 처리하고 직원 개체 목록을 생성합니다.
직원 정보를 추상화하기 위해 Employee 클래스를 사용합니다: Employee.java

package com.journaldev.xml;public class Employee {
    private int id;    
    private String name;    
    private String gender;    
    private int age;    
    private String role;    
    public int getId() {        
    return id;
    }    public void setId(int id) {        
    this.id = id;
    }    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;
    }    public int getAge() {        
    return age;
    }    public void setAge(int age) {        
    this.age = age;
    }    public String getRole() {        
    return role;
    }    public void setRole(String role) {        
    this.role = role;
    }    @Override
    public String toString() {        
    return "Employee:: ID="+this.id+" Name=" + this.name + " Age=" + this.age + " Gender=" + this.gender +       
             " Role=" + this.role;
    }

}

그런 다음 DefaultHandler 클래스를 상속하고 고유한 핸들러 클래스 MyHandler.java를 만듭니다.

package com.journaldev.xml.sax;
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.journaldev.xml.Employee;
public class MyHandler extends DefaultHandler {

    //List to hold Employees object
    private List<Employee> empList = null;    
    private Employee emp = null;    
    //getter method for employee list
    public List<Employee> getEmpList() {        
    return empList;
    }    
    boolean bAge = false;    
    boolean bName = false;    
    boolean bGender = false;    
    boolean bRole = false;    
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes)            
    throws SAXException {        
    if (qName.equalsIgnoreCase("Employee")) {            
    //create a new Employee and put it in Map
            String id = attributes.getValue("id");            
            //initialize Employee object and set id attribute
            emp = new Employee();
            emp.setId(Integer.parseInt(id));            
            //initialize list
            if (empList == null)
                empList = new ArrayList<>();
        } else if (qName.equalsIgnoreCase("name")) {            
        //set boolean values for fields, will be used in setting Employee variables
            bName = true;
        } else if (qName.equalsIgnoreCase("age")) {
            bAge = true;
        } else if (qName.equalsIgnoreCase("gender")) {
            bGender = true;
        } else if (qName.equalsIgnoreCase("role")) {
            bRole = true;
        }
    }    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {        
    if (qName.equalsIgnoreCase("Employee")) {            
    //add Employee object to list
            empList.add(emp);
        }
    }    @Override
    public void characters(char ch[], int start, int length) throws SAXException {        
    if (bAge) {            
    //age element, set Employee age
            emp.setAge(Integer.parseInt(new String(ch, start, length)));
            bAge = false;
        } else if (bName) {
            emp.setName(new String(ch, start, length));
            bName = false;
        } else if (bRole) {
            emp.setRole(new String(ch, start, length));
            bRole = false;
        } else if (bGender) {
            emp.setGender(new String(ch, start, length));
            bGender = false;
        }
    }
}

MyHandler 클래스는 저장소를 보유합니다. Employee 객체의 경우 해당 getter 메소드가 하나만 있는 목록 참조입니다. Employee 객체는 이벤트 처리 함수의 List 객체에 추가되며 Employee 객체의 모든 속성이 생성되면 Employee 객체와 관련된 여러 필드도 MyHandler 클래스에 정의됩니다. 설정하면 목록에 추가됩니다.
몇 가지 중요한 메소드인 startElement(), endElement() 및characters()를 다시 작성했습니다.
SAXParser가 문서 구문 분석을 시작하고 요소의 시작 태그를 발견하면 startElement() 메소드가 호출됩니다. 이 방법을 사용하고 부울 유형 변수를 사용하여 요소 카테고리를 구별합니다. Employee 태그가 시작될 때 Employee 객체를 생성하는 것도 이 메서드에서입니다.
SAXParser가 요소에서 문자열 데이터를 발견하면 문자() 메소드가 호출됩니다. 우리는 부울 유형 필드를 사용하여 Employee 객체의 속성에 값을 할당합니다. SAXParser가 XML 종료 태그를 발견하면
endElement() 메소드가 호출됩니다. 여기서는 Employee 객체를 List 객체에 추가합니다.
다음 테스트 프로그램에서는 MyHandler를 사용하여 XML 문서를 구문 분석하여 직원 개체 목록을 생성합니다.
XMLParserSAX.java

package com.journaldev.xml.sax;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import com.journaldev.xml.Employee;
public class XMLParserSAX {

    public static void main(String[] args) {
    SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
    try {
        SAXParser saxParser = saxParserFactory.newSAXParser();
        MyHandler handler = new MyHandler();
        saxParser.parse(new File("/Users/pankaj/employees.xml"), handler);
        //Get Employees list
        List<Employee> empList = handler.getEmpList();
        //print employee information
        for(Employee emp : empList)
            System.out.println(emp);
    } catch (ParserConfigurationException | SAXException | IOException e) {
        e.printStackTrace();
    }
    }

}

실행 중인 프로그램 출력:

Employee:: ID=1 Name=Pankaj Age=29 Gender=Male Role=Java DeveloperEmployee:: ID=2 Name=Lisa Age=35 
Gender=Female Role=CEOEmployee:: ID=3 Name=Tom Age=40 
Gender=Male Role=ManagerEmployee:: ID=4 Name=Meghna Age=25 Gender=Female Role=Manager

SAXParserFactory 클래스는 SAXParser 인스턴스를 얻기 위한 팩토리 메서드를 제공하며, SAXParser 객체의 구문 분석 메서드를 호출할 때 다음을 전달합니다. 콜백 이벤트를 처리하기 위한 Handler 객체. SAXParser 구문 분석 메커니즘은 처음에는 약간 복잡하지만 대규모 XML 문서를 처리하려고 하면 DOM 구문 분석보다 더 효율적인 구문 분석 메커니즘을 제공합니다.
원본 주소: http://www.php.cn/

Java SAX 구문 분석 메커니즘은 XML 파일을 처리하기 위한 일련의 API를 제공합니다. SAX 구문 분석은 DOM 구문 분석과 다릅니다. XML 파일은 한꺼번에 로드되지 않고, 부분적으로 연속적으로 로드됩니다.

javax.xml.parsers.SAXParser 클래스는 이벤트 처리를 사용하여 XML 문서를 구문 분석하는 몇 가지 기능을 제공하며 XMLReader 인터페이스를 구현하고 File, InputStream, SAX InputSource 및 URI 문자열에서 오버로드된 구문 분석() 메서드를 제공합니다. 문서.
실제 XML 구문 분석 작업은 Handler 클래스에 의해 완료됩니다. 이를 위해서는 org.xml.sax.ContentHandler 인터페이스를 구현해야 하는 자체 Handler 클래스를 만들어야 합니다. 이 인터페이스에는 StartDocument, EndDocument, StartElement, EndElement, CharacterData 등과 같은 이벤트가 발생할 때 알림을 받는 콜백 메서드가 포함되어 있습니다.

org.xml.sax.helpers.DefaultHandler은 ContentHandler 인터페이스의 기본 구현을 제공하므로 이 클래스를 상속하여 자체 처리 클래스를 구현할 수 있습니다. 이 클래스를 상속받는 것은 몇 가지 메서드만 구현하면 되기 때문에 현명한 선택입니다. 이 클래스를 상속하면 코드의 단순성과 유지 관리 가능성이 보장됩니다.
다음은 구문 분석하려는 XML 문서입니다.
employees.xml

<?xml version="1.0" encoding="UTF-8"?><Employees>
    <Employee id="1">
        <age>29</age>
        <name>Pankaj</name>
        <gender>Male</gender>
        <role>Java Developer</role>
    </Employee>
    <Employee id="2">
        <age>35</age>
        <name>Lisa</name>
        <gender>Female</gender>
        <role>CEO</role>
    </Employee>
    <Employee id="3">
        <age>40</age>
        <name>Tom</name>
        <gender>Male</gender>
        <role>Manager</role>
    </Employee>
    <Employee id="4">
        <age>25</age>
        <name>Meghna</name>
        <gender>Female</gender>
        <role>Manager</role>
    </Employee></Employees>

이 XML 파일의 내용은 일부 직원 정보를 저장합니다. 각 직원에는 ID 속성과 나이, 이름, 성별 및 역할 필드.
SAX 구문 분석 메커니즘을 사용하여 XML 파일을 처리하고 직원 개체 목록을 생성합니다.
직원 정보를 추상화하기 위해 Employee 클래스를 사용합니다: Employee.java

package com.journaldev.xml;public class Employee {
    private int id;    
    private String name;    
    private String gender;    
    private int age;    
    private String role;    
    public int getId() {        
    return id;
    }    public void setId(int id) {        
    this.id = id;
    }    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;
    }    public int getAge() {        
    return age;
    }    public void setAge(int age) {        
    this.age = age;
    }    public String getRole() {        
    return role;
    }    public void setRole(String role) {        
    this.role = role;
    }    @Override
    public String toString() {        
    return "Employee:: ID="+this.id+" Name=" + this.name + " Age=" + this.age + " Gender=" + this.gender +         
           " Role=" + this.role;
    }

}

그런 다음 DefaultHandler 클래스를 상속하여 자체 핸들러 클래스 MyHandler.java를 만듭니다.

package com.journaldev.xml.sax;
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.journaldev.xml.Employee;
public class MyHandler extends DefaultHandler {

    //List to hold Employees object
    private List<Employee> empList = null;    
    private Employee emp = null;    
    //getter method for employee list
    public List<Employee> getEmpList() {        
    return empList;
    }    
    boolean bAge = false;    
    boolean bName = false;    
    boolean bGender = false;    
    boolean bRole = false;    
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes)            
    throws SAXException {        
    if (qName.equalsIgnoreCase("Employee")) {            
    //create a new Employee and put it in Map
            String id = attributes.getValue("id");            
            //initialize Employee object and set id attribute
            emp = new Employee();
            emp.setId(Integer.parseInt(id));            
            //initialize list
            if (empList == null)
                empList = new ArrayList<>();
        } else if (qName.equalsIgnoreCase("name")) {            
        //set boolean values for fields, will be used in setting Employee variables
            bName = true;
        } else if (qName.equalsIgnoreCase("age")) {
            bAge = true;
        } else if (qName.equalsIgnoreCase("gender")) {
            bGender = true;
        } else if (qName.equalsIgnoreCase("role")) {
            bRole = true;
        }
    }    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {        
    if (qName.equalsIgnoreCase("Employee")) {            
    //add Employee object to list
            empList.add(emp);
        }
    }    @Override
    public void characters(char ch[], int start, int length) throws SAXException {        
    if (bAge) {            
    //age element, set Employee age
            emp.setAge(Integer.parseInt(new String(ch, start, length)));
            bAge = false;
        } else if (bName) {
            emp.setName(new String(ch, start, length));
            bName = false;
        } else if (bRole) {
            emp.setRole(new String(ch, start, length));
            bRole = false;
        } else if (bGender) {
            emp.setGender(new String(ch, start, length));
            bGender = false;
        }
    }
}

MyHandler类持有一个存放Employee对象的List引用,它只有一个对应的getter方法。Employee对象在事件处理函数中被添加到List对象,在MyHandler类中还定义了Employee对象和它的几个字段相关的boolean类型变量用于创建Employee对象,当Employee对象的所有属性都被设置时,它就会被添加到list中。
我们重写了几个重要的方法startElement(), endElement() 和characters().
当SAXParser 开始解析文档时遇到元素的开始标签时,startElement() 方法就会被调用,我们重写了这个方法,使用boolean类型变量来区分元素类别。我们也是在该方法中,当Employee 标签开始时创建Employee 对象。
当SAXParser遇到元素中的字符串数据时characters()方法会被调用,我们使用boolean类型字段为Employee对象的属性进行赋值。
endElement()方法则会在SAXParser 遇到XML结束标签时会被调用,在这里我们將Employee对象添加到List对象中。
在下面的测试程序中,我们使用MyHandler解析XML文档生成存放Employee 对象List。
XMLParserSAX.java

package com.journaldev.xml.sax;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import com.journaldev.xml.Employee;
public class XMLParserSAX {

    public static void main(String[] args) {
    SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
    try {
        SAXParser saxParser = saxParserFactory.newSAXParser();
        MyHandler handler = new MyHandler();
        saxParser.parse(new File("/Users/pankaj/employees.xml"), handler);
        //Get Employees list
        List<Employee> empList = handler.getEmpList();
        //print employee information
        for(Employee emp : empList)
            System.out.println(emp);
    } catch (ParserConfigurationException | SAXException | IOException e) {
        e.printStackTrace();
    }
    }

}

运行程序输出:

Employee:: ID=1 Name=Pankaj Age=29 Gender=Male Role=Java 
DeveloperEmployee:: ID=2 Name=Lisa Age=35 Gender=Female Role=CEOEmployee:: ID=3 Name=Tom Age=40 
Gender=Male Role=ManagerEmployee:: ID=4 Name=Meghna Age=25 Gender=Female Role=Manager

SAXParserFactory 类提供了工厂方法来获取SAXParser 实例,在调用 SAXParser对象的parse方法时传入Handler对象来处理回调事件。SAXParser解析机制刚开始接触时有点复杂,但是当你致力于处理大型的XML文档时,它比DOM解析提供了更有效的解析机制。

以上就是Java&Xml教程(五)使用SAX方式解析XML文件的内容,更多相关内容请关注PHP中文网(www.php.cn)!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.