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

标签 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>

当我找到 <id> 时,我正在迭代 Design XML 节点。标记文本 (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>

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

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;

    }

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

Node org.w3c.dom.Node.appendChild(Node newChild) throws DOMException

Adds the node newChild to the end of the list of children of this node. If the newChild is already in the tree, it is first removed.

有什么想法吗?

最佳答案

选项 1: newChild 不会被删除,因为每次追加时都会通过 createTextNode() 方法创建一个新的 Node 对象。如果您添加了 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;
            }               
        }
    }
}

关于java node.appendChild 没有删除以前的标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46649632/

相关文章:

java - 关闭应用程序后服务未运行

java - 播放框架2 : How to access default values for hidden form fields in view templates?

android - Recyclerview 布局未在 fragment 内正确显示

Javascript - 获取 child 的文本值

javascript - 如何使用 Puppeteer 求解和定位元素

java - 如何将数据从 fragment 传递到适配器

java - .jnlp 文件将无法运行(来源未知)

android - 为什么android中xml的style属性没有命名空间

java - 使用 JAXB 解析 XML

c# - 使用 C# 以编程方式删除 HtmlElement 对象