在 java 中使用 STAX 解析的一些建议

some suggestions for using STAX Parsing in java

我有一个 XML 文档,它的顶部有数据库配置,如用户名、密码和 URL,然后它有一个名为数据的标签,里面有关于员工的数据和有关部门的数据,我想从 XML 中提取并将其插入数据库。

我已经设法读取 JDBC 配置并将其设置在一个 return 连接并成功工作的 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 class:

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

我发现 XMLStreamReader 更容易使用,因为元素可以在父级的上下文中处理,不像 XMLEventReader returns 所有事件都在一个平面序列中。

使用 XMLStreamReader 解析 XML 的示例。为简单起见,代码忽略了命名空间。

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
}