Как скопировать узлы DOM из одного документа в другой в Java? - PullRequest
28 голосов
/ 17 мая 2009

У меня проблемы с копированием узлов из одного документа в другой. Я использовал оба метода acceptNode и importNode из Node, но они не работают. Я также попробовал appendChild, но это вызывает исключение. Я использую Xerces. Это там не реализовано? Есть ли другой способ сделать это?

List<Node> nodesToCopy = ...;
Document newDoc = ...;
for(Node n : nodesToCopy) {
    // this doesn't work
    newDoc.adoptChild(n);
    // neither does this
    //newDoc.importNode(n, true);
}

Ответы [ 2 ]

69 голосов
/ 17 мая 2009

Проблема в том, что узлы содержат много внутреннего состояния относительно своего контекста, который включает их происхождение и документ, которым они принадлежат. Ни adoptChild(), ни importNode() не помещайте новый узел где-либо в целевом документе, поэтому ваш код не работает.

Поскольку вы хотите скопировать узел, а не перемещать его из одного документа в другой, вам необходимо выполнить три отдельных шага ...

  1. Создать копию
  2. Импорт скопированного узла в целевой документ
  3. Поместите скопированное в правильное положение в новом документе
for(Node n : nodesToCopy) {
    // Create a duplicate node
    Node newNode = n.cloneNode(true);
    // Transfer ownership of the new node into the destination document
    newDoc.adoptNode(newNode);
    // Make the new node an actual item in the target document
    newDoc.getDocumentElement().appendChild(newNode);
}

Java Document API позволяет комбинировать первые две операции, используя importNode().

for(Node n : nodesToCopy) {
    // Create a duplicate node and transfer ownership of the
    // new node into the destination document
    Node newNode = newDoc.importNode(n, true);
    // Make the new node an actual item in the target document
    newDoc.getDocumentElement().appendChild(newNode);
}

Параметр true в cloneNode() и importNode() указывает, требуется ли вам глубокое копирование, то есть копировать узел и все его дочерние элементы. Поскольку в 99% случаев вы хотите скопировать целое поддерево, вы почти всегда хотите, чтобы это было правдой.

4 голосов
/ 17 мая 2009

acceptChild не создает дубликат, он просто перемещает узел к другому родителю.

Возможно, вам нужен метод cloneNode ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...