Некоторые предложения по использованию STAX Parsing в Java

У меня есть документ XML, в верхней части которого находятся конфигурации базы данных, такие как имя пользователя, пароль и URL, и после этого у него есть тег с именем data, а внутри него есть данные о сотрудниках и данные об отделе, которые я хочу извлечь из XML и вставьте его в базу данных.

Мне удалось прочитать конфигурацию JDBC и установить ее в bean-компоненте, который возвращает соединение и успешно работал, но теперь моя проблема с тегом данных, как я могу игнорировать конфигурацию JDBC из файла XML, прочитать тег данных и вставить его в базу данных, я знаю, что могу сделать это как

if (event.isStartElement()) {
    StartElement startElement = event.asStartElement();
    currentName = startElement.getName();
    if(!currentName.equals("connection-setteings")) ...

Но это не очень хорошая идея, так как я считаю, что кто-то может посоветовать лучший подход к этому?

Вот файл XML:

<?xml version="1.0" encoding="UTF-8"?>
<import-request xmlns="http://www.phi01tech.com/tools/data-import" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.phi01tech.com/tools/data-import data-import.xsd ">
    <connection-settings>
        <username>root</username>
        <password>root</password>
        <url>jdbc:mysql://localhost:3306/sample</url>
        <driverClassName>com.mysql.jdbc.Driver</driverClassName>
    </connection-settings>
    <data>
        <departments dept_no="d009" dept_name="Customer Service"/>
        <departments dept_no="d005" dept_name="Development"/>
        <departments dept_no="d002" dept_name="Finance"/>
        <departments dept_no="d003" dept_name="Human Resources"/>
        <departments dept_no="d001" dept_name="Marketing"/>
        <departments dept_no="d004" dept_name="Production"/>
        <departments dept_no="d006" dept_name="Quality Management"/>
        <departments dept_no="d008" dept_name="Research"/>
        <departments dept_no="d007" dept_name="Sales"/>
        <employees emp_no="10001" birth_date="1953-09-02" first_name="Georgi" last_name="Facello" gender="M"
                   hire_date="1986-06-26"/>
        <employees emp_no="10002" birth_date="1964-06-02" first_name="Bezalel" last_name="Simmel" gender="F"
                   hire_date="1985-11-21"/>
        <employees emp_no="10003" birth_date="1959-12-03" first_name="Parto" last_name="Bamford" gender="M"
                   hire_date="1986-08-28"/>
        <employees emp_no="10004" birth_date="1954-05-01" first_name="Chirstian" last_name="Koblick" gender="M"
                   hire_date="1986-12-01"/>
        <employees emp_no="10005" birth_date="1955-01-21" first_name="Kyoichi" last_name="Maliniak" gender="M"
                   hire_date="1989-09-12"/>
        <employees emp_no="10006" birth_date="1953-04-20" first_name="Anneke" last_name="Preusig" gender="F"
                   hire_date="1989-06-02"/>
        <employees emp_no="10007" birth_date="1957-05-23" first_name="Tzvetan" last_name="Zielinski" gender="F"
                   hire_date="1989-02-10"/>
        <employees emp_no="10008" birth_date="1958-02-19" first_name="Saniya" last_name="Kalloufi" gender="M"
                   hire_date="1994-09-15"/>
    </data>
</import-request>

И вот мой класс Java:

public class STAXParser {
    static ConnectionManager connectionManager = new ConnectionManager();
    String currentName;

    public void parseDocuments() throws IOException, XMLStreamException {
        XMLInputFactory inputFactory = XMLInputFactory.newFactory();
        try (InputStream stream = Files.newInputStream(Paths.get("emp.xml"))) {
            XMLEventReader reader = inputFactory.createXMLEventReader(stream);
            while (reader.hasNext()) {
                XMLEvent event = reader.nextEvent();
                if (event.isStartElement()) {
                    StartElement startElement = event.asStartElement();
                    currentName = startElement.getName().getLocalPart();
                    System.out.println(startElement.getName());
                    Iterator attributes = startElement.getAttributes();
                    while(attributes.hasNext()) {
                       //System.out.println(attributes.next());
                    }
                }
                if (event.isCharacters()) {
                    if (!event.asCharacters().isWhiteSpace()) {
                        String data = event.asCharacters().getData();
                        checkName(currentName, data.trim());
                    }
                }
            }
        }
    }

    private void checkName(String name, String event) {
        if (name.equals("url"))
            connectionManager.setUrl(event);
        else if (name.equals("username"))
            connectionManager.setUsername(event);
        else if (name.equals("password"))
            connectionManager.setPassword(event);
        else if (name.equals("driverClassName"))
            connectionManager.setDriver(event);
    }

    public static void main(String[] args) {
        STAXParser s = new STAXParser();
        try {
            s.parseDocuments();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (XMLStreamException e) {
            e.printStackTrace();
        }
        try {
            connectionManager.getConnection().toString();
            JDBCEmployeeDao d = new JDBCEmployeeDao(connectionManager);
//            d.create();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

1 ответ

Решение

Я нахожу это XMLStreamReader гораздо проще в использовании, так как элементы могут обрабатываться в контексте родительского, в отличие от XMLEventReader который возвращает все события в плоской последовательности.

Пример разбора вашего XML с использованием XMLStreamReader, Для простоты примера код игнорирует пространства имен.

public static void main(String[] args) throws Exception {
    XMLInputFactory inputFactory = XMLInputFactory.newFactory();
    Connection connection = null;
    try (InputStream stream = Files.newInputStream(Paths.get("src/main/resources/test.xml"))) {
        XMLStreamReader reader = inputFactory.createXMLStreamReader(stream);
        reader.nextTag(); // Position on root tag
        if (! reader.getLocalName().equals("import-request"))
            throw new XMLStreamException("Invalid root element: " + reader.getLocalName());
        while (reader.nextTag() == XMLStreamConstants.START_ELEMENT) {
            switch (reader.getLocalName()) {
                case "connection-settings":
                    connection = parseConnectionSettings(reader);
                    break;
                case "data":
                    if (connection == null)
                        throw new XMLStreamException("Missing <connection-settings> before <data>");
                    parseData(reader, connection);
                    break;
                default:
                    // ignore unknown content
            }
        }
    } finally {
        if (connection != null)
            connection.close();
    }
}

private static Connection parseConnectionSettings(XMLStreamReader reader) throws Exception {
    String username = null, password = null, url = null, driverClassName = null;
    while (reader.nextTag() == XMLStreamConstants.START_ELEMENT) {
        switch (reader.getLocalName()) {
            case "username":
                username = reader.getElementText();
                break;
            case "password":
                password = reader.getElementText();
                break;
            case "url":
                url = reader.getElementText();
                break;
            case "driverClassName":
                driverClassName = reader.getElementText();
                break;
            default:
                throw new XMLStreamException("Invalid element in <connection-settings>: " + reader.getLocalName());
        }
    }
    Class.forName(driverClassName);
    return DriverManager.getConnection(url, username, password);
}

private static void parseData(XMLStreamReader reader, Connection connection) throws Exception {
    while (reader.nextTag() == XMLStreamConstants.START_ELEMENT) {
        switch (reader.getLocalName()) {
            case "departments":
                processDepartments(reader, connection);
                break;
            case "employees":
                processEmployees(reader, connection);
                break;
            default:
                throw new XMLStreamException("Invalid element in <data>: " + reader.getLocalName());
        }
    }
}

private static void processDepartments(XMLStreamReader reader, Connection connection) throws Exception {
    String dept_no = reader.getAttributeValue(null, "dept_no");
    String dept_name = reader.getAttributeValue(null, "dept_name");
    if (! reader.getElementText().isEmpty())
        throw new XMLStreamException("<departments> must be empty element");
    // process here
}

private static void processEmployees(XMLStreamReader reader, Connection connection) throws Exception {
    // code here
}
Другие вопросы по тегам