java - 使用 DOM 将 XML 解析为 HashMap

标签 java xml parsing dom hashmap

我彻底搜索了我的问题的答案,但没有得到它。我的任务就是这样的。我有一个 XML:

<?xml version="1.0" encoding="utf-8" ?>
<users>
    <user id="1">
        <login>james.bond</login>
        <password>12345</password>
        <enabled>true</enabled>
    </user>
    <user id="2">
        <login>john.doe</login>
        <password>67890</password>
        <enabled>false</enabled>
    </user>
</users>

我想将它解析为 HashMap,其中键和值应该是这样的(通过句点的节点名称作为键,这些节点的值作为映射中的值):

K: users.user.1.login V: james.bond

K: users.user.1.password V: 12345

等等...

就在我拥有的那一刻:

public Map<String, String> parse(File file) {
        Document doc = null;

        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();

            dbf.setIgnoringComments(true);

            doc = db.parse(file);
        } catch (ParserConfigurationException pce) {
            System.out.println("Parser was not configured properly [LOG IT!]");
        } catch (IOException io) {
            System.out.println("Cannot read input file [LOG IT!]");
        } catch (SAXException se) {
            System.out.println("Problem parsing the file [LOG I!]");
        } catch (IllegalArgumentException ae) {
            System.out.println("Please specify an XML source [LOG IT!]");
        }

        Element root = doc.getDocumentElement();

        return stepThrough(root);
    }

private Map<String, String> stepThrough(Node node) {
        String nodeName =  node.getNodeName();

        if (!nodeName.equals("#text")) {
            buildedKey.append(nodeName).append(".");
        }

        if (node.getNodeValue() != null && !node.getNodeValue().matches("^\\W*$")) {
            parsedMap.put(buildedKey.toString(),node.getNodeValue());
        }

        if (node.getNodeType() == Node.ELEMENT_NODE) {
            if (node.hasAttributes()) {
                NamedNodeMap startAttr = node.getAttributes();
                for (int i = 0; i < startAttr.getLength(); i++) {
                    Node attr = startAttr.item(i);
                    buildedKey.append(attr.getNodeValue()).append(".");
                }
            }
        }

        for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
            stepThrough(child);
        }

        return parsedMap;
    }

例如,我的 map 中有最后一个键: users.user.1.login.password.enabled.user.2.login.password.enabled

换句话说,所有节点名称都是串联的。

你愿意帮助我吗?谢谢!

P.S.:我有一个限制,我不能使用像 XStream 这样的库...

最佳答案

问题是您在所有遍历中使用相同的全局buildedKey,并且当您从stepThrough返回时,您没有删除添加的部分。简单的解决方案是将 buildedKey 作为参数传递,而不是使用全局变量:

private Map<String, String> stepThrough(Node node, String buildedKey) {
        String nodeName =  node.getNodeName();

        if (!nodeName.equals("#text")) {
            buildedKey += nodeName + ".";
        }

        if (node.getNodeValue() != null && !node.getNodeValue().matches("^\\W*$")) {
            parsedMap.put(buildedKey,node.getNodeValue());
        }

        if (node.getNodeType() == Node.ELEMENT_NODE) {
            if (node.hasAttributes()) {
                NamedNodeMap startAttr = node.getAttributes();
                for (int i = 0; i < startAttr.getLength(); i++) {
                    Node attr = startAttr.item(i);
                    buildedKey += attr.getNodeValue() + ".";
                }
            }
        }

        for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
            stepThrough(child, buildedKey);
        }

        return parsedMap;
    }

此外,您最好使用 String 作为 buildedKey 而不是 StringBuilder,因为 String 是不可变的,而您不可以想要破坏一个节点中的builtKey并在另一个节点中使用相同的破坏 key 。

关于java - 使用 DOM 将 XML 解析为 HashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14676423/

相关文章:

c++ - 在 C++ 中解析数学表达式

java - Android Studio,如何动态更改对话框中的 View ,案例 : Retrofit onSuccess

ios - AFNetworking 2.0 不解析 xml

xml - Xpath3-从SOAP消息获取名称

java - 将 XML 字符串转换为 JSON 对象时删除前面的 0

parsing - munch 和 many(满足 p)的区别?

java - 如何在 Cucumber 中使用 Java 将已实现的步骤从一个步骤定义调用到另一个步骤定义中

java - 如何使用 hibernate CRITERIA 编写此连接查询

java - 通过 telnet.exe 与 Java 服务器套接字通信

java - 与 "nbsp"相关的 Xpath 错误