@dieillusion

Как использовать SAX-парсер для сохранения только дочерних элементов и хранение их в коллекции?

Есть xml файл

<shop>
    	<department number= "1" name="unknown">
    		<product id="1"/>
    		<product id="2"/>
    		<product id="3"/>
    	</department>
    	<department number= "2" name="unknown">
    		<product id="4"/>
    		<product id="5"/>
    		<product id="6"/>
    	</department>
    	<department number= "3" name="unknown">
    		<.../>
    	</department>
    </shop>


Для сохранения информации при парсинге я создал класс `Department` и коллекцию `ArrayList`, чтобы эти классы там хранить. Сам класс выглядит так:

class Department {
        String number;
        String name;
        ArrayList<Integer> productId = new ArrayList<>(); // коллекция для хранения аттрибутов product id
        //конструктор
        public Department(String n, String na, ArrayList<Integer> pr) {
            this.number = n;
            this.name = na;
            this.productId = pr;
        }
    }

Как мне организовать работу парсера чтобы в каждый экземпляр класса `Departament` попадали только его дочерние теги product id и помещались в конкретный `ArrayList`?
  • Вопрос задан
  • 338 просмотров
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Java
Седой и строгий
import java.io.IOException;

import java.util.List;
import java.util.ArrayList;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

class Department {
    private String number;
    private String name;
    private List<Integer> products;

    public Department(String number, String name) {
        this.number = number;
        this.name = name;
        this.products = new ArrayList<>();
    }
    
    public void setProducts(List<Integer> products) {
        this.products = products;
    }
    
    public String toString() {
        return String.format("Name: %s\nNumber: %s\nProducts: %s\n", name, number, products);
    }
}

public class SAXHandler extends DefaultHandler {
    private List<Department> departments;
    private List<Integer> products;
    private Department currentDepartment;
    
    public SAXHandler() {
        this.departments = new ArrayList<>();
    }
    
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if(qName.equals("department")) {
            String name = attributes.getValue("name");
            String number = attributes.getValue("number");
            
            products = new ArrayList<>();

            currentDepartment = new Department(name, number);
        }
        
        if(qName.equals("product")) {
            String id = attributes.getValue("id");
            products.add(Integer.valueOf(id));
        }
    }
    
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if(qName.equals("department")) {
            currentDepartment.setProducts(products);
            departments.add(currentDepartment);
        }
	}
    
    public List<Department> getResult() {
        return departments;
    }

    public static void main(final String args[]) {
        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();
    
            SAXHandler handler = new SAXHandler();
            saxParser.parse("test.xml", handler);
        
            handler.getResult().stream().forEach(System.out::println);
        }
        catch(SAXException ex) {}
        catch(ParserConfigurationException ex) {}
        catch(IOException ex) {}
    }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы