java node.appendChild没有删除以前的标记

时间:2017-10-09 15:09:12

标签: java xml dom

我试图合并两个XML文档,有两个简单的例子:

设计XML:

<element type="INPUT-TEXT">
    <id>id1</id>
    <name>Id1</name>
    <order>1</order>
    <required>false</required>
</element>

回答XML:

<form>
    <id1>answer1</id1>
</form>

我通过设计XML节点进行迭代,当我找到<id>标记文本(id1)时,我通过Answer XML迭代,然后搜索<id1>标记名称并将其添加到以这种方式设计XML:

<element type="INPUT-TEXT">
    <id>id1</id>
    <name>Id1</name>
    <order>1</order>
    <required>false</required>
    <answer>answer1</answer>
</element>

这是正确的,但如果我再试一次,我会得到一个重复的答案标记:

<element type="INPUT-TEXT">
    <id>id1</id>
    <name>Id1</name>
    <order>1</order>
    <required>false</required>
    <answer>answer1</answer>
    <answer>newAnswer1</answer>
</element>

我需要覆盖答案标记值。 这是我使用appendChild方法的Java方法:

public String createEditableXML(String xml) {

        try {
            Document document;
            Document documentAnswer;

            document = _loadXMLFromString(xml);
            documentAnswer = _loadXMLFromString(vars);

            String child = null;

            // Design xml part
            NodeList nodeList1 = document.getChildNodes();
            NodeList nodeList = nodeList1.item(0).getChildNodes();
            for (int i = 0; i < nodeList.getLength(); i++) {
                Node node = nodeList.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("element")) {

                    // Taking id to compare with the answer XML
                    NodeList childNode = node.getChildNodes();
                    for (int n = 0; n < childNode.getLength(); n++) {
                        if (childNode.item(n).getNodeName().equals("id")) {
                            child = childNode.item(n).getTextContent();
                            break;
                        }
                    }

                    // Adding the anwser to the original document
                    NodeList answerNodeList = documentAnswer.getElementsByTagName("*");
                    for (int m = 1; m < answerNodeList.getLength(); m++) {
                        Node answerNode = answerNodeList.item(m);
                        if (answerNode.getNodeType() == Node.ELEMENT_NODE) {
                            if (child.equals(answerNode.getNodeName())) {
                                Element answer = document.createElement("answer");
                                answer.appendChild(document.createTextNode(answerNode.getTextContent()));
                                node.appendChild(answer);
                                break;
                            }
                        }
                    }
                }
            }

            return _nodeListToString(nodeList1);

        } catch (Exception e) {
            String mess = "createEditableXML(): " + (e.getMessage() != null ? ". " + e.getMessage() : "")
                    + (e.getCause() != null ? ". " + e.getCause() : "");
            logger.error(mess);
        }
        return null;

    }

方法说明会用新的替换答案标签。

  

节点org.w3c.dom.Node.appendChild(Node newChild)抛出DOMException

     

将节点newChild添加到此子节点列表的末尾   节点。如果newChild已经在树中,则首先将其删除。

有些想法?

1 个答案:

答案 0 :(得分:1)

选项1:不会删除newChild,因为每次追加时都会创建一个新的Node对象,方法createTextNode()。如果您添加了newChild并尝试添加完全相同的对象,则会删除旧对象。要么找到保存答案textNode引用的方法

选项2:当您找到匹配的ID时,检查是否已存在应答节点,如果已存在,请更新它,而不是附加新的应答节点。这样您就不必保存先前创建的答案节点的引用。

示例(代码未经过测试,只是帮助您前进的想法):

//I suggest to use constants
private static final String ANSWER_NODE_NAME = "answer";

// Adding the anwser to the original document
NodeList answerNodeList = documentAnswer.getElementsByTagName("*");
for (int m = 1; m < answerNodeList.getLength(); m++) {
    Node answerNode = answerNodeList.item(m);
    if (answerNode.getNodeType() == Node.ELEMENT_NODE) {
        if (child.equals(answerNode.getNodeName())) {


            //Check if answer node already exists
            //if it does, update its content instead of appending a new answer node
            NodeList children = node.getChildNodes();

            boolean answerNodeExists = false;
            for(int j = 1; j < children.getLength(); j++){
                Node origDocumentChild = children.item(j);

                //check if node is <answer>
                if (origDocumentChild.getNodeName().equals(ANSWER_NODE_NAME)) {

                    //set new answer content
                    origDocumentChild.setTextContent("new answer 123");
                    answerNodeExists = true;
                    break;
                }
            }

            if (!answerNodeExists) {
                Element answer = document.createElement("answer");
                answer.appendChild(document.createTextNode(answerNode.getTextContent()));
                node.appendChild(answer);
                break;
            }               
        }
    }
}