0

質問に対する答えを徹底的に検索しましたが、見つかりませんでした。私の仕事はそのようなものです。私は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;
    }

そして、マップに最後のキーがあります。たとえば、 users.user.1.login.password.enabled.user.2.login.password.enabledです。

つまり、すべてのノード名が連結されています。

手伝ってくれませんか?ありがとう!

PS:制限が1つあり、XStreamのようなライブラリを使用できません...

4

1 に答える 1

2

問題は、すべてのトラバースに同じグローバルbuildedKeyを使用していて、 from に戻るときに追加された部分を削除しないことですstepThroughbuildedKey簡単な解決策は、グローバル変数を使用する代わりにパラメーターとして渡すことです。

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

また、 is immutable の代わりにStringforを使用することをお勧めします。また、あるノードで builtKey を台無しにして、別のノードで同じ台無しにされたキーを使用したくない場合もあります。buildedKeyStringBuilderString

于 2013-02-03T19:45:46.967 に答える