Como adicionar um elemento XML em Java 1.4
Pergunta
Eu estou tentando adicionar um elemento "título", mas estou recebendo um erro NO_MODIFICATION_ALLOWED_ERR ...
private static void saveDoc(String f) throws Exception
{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(f);
// create DOMSource for source XML document
DOMSource xmlSource = new DOMSource(doc);
Node nextNode = xmlSource.getNode().getFirstChild();
while (nextNode != null)
{
System.out.print("\n node name: " + nextNode.getNodeName() + "\n");
if (nextNode.getNodeName().equals("map")){
nextNode.appendChild(doc.createElement("title"));
a linha acima está jogando erro: Exception in thread "main" org.w3c.dom.DOMException: NO_MODIFICATION_ALLOWED_ERR
: É feita uma tentativa para modificar um objeto onde as modificações não são permitidos.
em com.sun.org.apache.xerces.internal.dom.ParentNode.internalInsertBefore (fonte desconhecida)
em com.sun.org.apache.xerces.internal.dom.ParentNode.insertBefore (fonte desconhecida)
em com.sun.org.apache.xerces.internal.dom.NodeImpl.appendChild (fonte desconhecida)
em myProject.Main.saveDoc (Main.java:171)
em myProject.Main.main (Main.java:48)
break;
}
nextNode = nextNode.getNextSibling();
}
}
As minhas xml aparência de arquivo como este:
<?xml version="1.0" encoding="UTF-8"?>
<?dctm xml_app="LOPackage"?>
<!DOCTYPE map PUBLIC "-//OASIS//DTD DITA Map//EN" "file:C:/Documents%20and%20Settings/joe/Desktop//LOPackage/map.dtd">
<map xmlns:ditaarch="http://dita.oasis-open.org/architecture/2005/" class="- map/map " ditaarch:DITAArchVersion="1.1" domains="(map mapgroup-d) (topic indexing-d)">
<topicref class="- map/topicref " href="dctm://ai/0501869e80002504?DMS_OBJECT_SPEC=RELATION_ID" type="Le"/>
<topicref class="- map/topicref " href="dctm://ai/0501869e80002505?DMS_OBJECT_SPEC=RELATION_ID" type="Pr"/>
<topicref class="- map/topicref " href="dctm://ai/0501869e80002506?DMS_OBJECT_SPEC=RELATION_ID" type="Pr"/>
</map>
Solução
Não tenho certeza se essa é a razão, mas verifique se sua implementação DOM valida todas as alterações no DOM. Porque em você código,
nextNode.appendChild(doc.createTextNode("title"));
tentará criar um nó de texto como o filho de elemento map
e não DITA Mapa não permitir isso. Em vez disso, tente
Element title = doc.createElement("title");
title.appendChild(doc.createTextNode("title content"))
nextNode.appendChild(title);
Outras dicas
Por alguma razão, o nó pai parece ser somente leitura. Clonar o documento usando:
Document newDoc = doc.cloneNode(true);
Set-lo para leitura e escrita por:
newDoc.setReadOnly(false,true);
// ^^^^ also sets children
Em seguida, faça o seu material. Eu gostaria de voltar o novo documento após salvá-lo embora.
Onde está o documento original vem?
Essa é a causa do problema - o código que está lendo no documento é a construção de um documento só de leitura. Sem saber como você está lendo isso em, é muito difícil descobrir como mudar isso.
Eu apenas fiz um teste rápido no Windows com JDK 1.4.2-11, e posso confirmar que a utilização do DocumentBuilderFactory (com o conteúdo XML vindo de uma Reader) não cria uma leitura único documento.