Я пытаюсь добавить элемент "title", но получаю ошибку 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"));
строка выше выдает ошибку:
Exception in thread "main" org.w3c.dom.DOMException:
NO_MODIFICATION_ALLOWED_ERR: An attempt is made to modify an object where modifications are not allowed. at com.sun.org.apache.xerces.internal.dom.ParentNode.internalInsertBefore(Unknown Source) at com.sun.org.apache.xerces.internal.dom.ParentNode.insertBefore(Unknown Source) at com.sun.org.apache.xerces.internal.dom.NodeImpl.appendChild(Unknown Source) at myProject.Main.saveDoc(Main.java:171) at myProject.Main.main(Main.java:48)
break;
}
nextNode = nextNode.getNextSibling();
}
}
Мой xml-файл выглядит так:
<?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>




По какой-то причине кажется, что родительский узел доступен только для чтения. Клонируйте документ, используя:
Document newDoc = doc.cloneNode(true);
Установите его на чтение-запись:
newDoc.setReadOnly(false,true);
// ^^^^ also sets children
Тогда делайте свое дело. Я бы вернул новый документ после его сохранения.
Откуда исходный документ?
Это причина проблемы - код, который читается в документе, создает документ только для чтения. Не зная, как вы это читаете, довольно сложно придумать, как это изменить.
Я только что провел быстрый тест в Windows с JDK 1.4.2-11 и могу подтвердить, что использование DocumentBuilderFactory (с XML-контентом, поступающим из Reader) не создает документ только для чтения.
Не уверен, что это причина, но проверьте, подтверждает ли ваша реализация DOM все изменения в DOM. Потому что в вашем коде
nextNode.appendChild(doc.createTextNode("title"));
попытается создать текстовый узел как дочерний для элемента map, а DITA Map не позволяет этого. Вместо этого попробуйте
Element title = doc.createElement("title");
title.appendChild(doc.createTextNode("title content"))
nextNode.appendChild(title);
Хорошее понимание. Но я изменил код (и обновил вопрос), возникает та же проблема.
ни Node, ни Document не имеют свойства setReadOnly в версии 1.4. Не могли бы вы мне с этим помочь?