2

Hello I am getting NO modification allowed when trying to add a new node to an xml file and I am not sure why because I am using the same code for another file and it works fine, here is the code:

 public void addStockItem(String itemStr, int qty){
    String path = System.getProperty("user.dir") + "/src/stock.xml";
      try {
    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        docFactory.setIgnoringElementContentWhitespace(true);

        DocumentBuilder docBuilder;      

        docBuilder = docFactory.newDocumentBuilder();

        Document doc = docBuilder.parse(path);

        Node root = doc.getFirstChild();

        Node item = doc.createElement("item");
        item.setTextContent(itemStr);
        NamedNodeMap itemAttr = item.getAttributes();
        Attr qtyAttr = doc.createAttribute("quantity");
        qtyAttr.setTextContent(qty+"");
        itemAttr.setNamedItem(qtyAttr);
        root.appendChild(item);

        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");

        //initialize StreamResult with File object to save to file
        StreamResult result = new StreamResult(new StringWriter());
        DOMSource source = new DOMSource(doc);
        transformer.transform(source, result);
        String xmlString = result.getWriter().toString();

        BufferedWriter out = new BufferedWriter(new FileWriter(path));
        out.write(xmlString);
        out.close();

    } catch (Exception ex) {
        System.out.print(ex);

    }

}

My xml is the following:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE stock SYSTEM "barstock.dtd">

<stock>
   <item quantity="23">dark rum</item>
   <item quantity="5">light rum</item>
   <item quantity="4">vodka</item>
   <item quantity="2">brandy</item>
   <item quantity="3">orange juice</item>
   <item quantity="2">cream</item>
   <item quantity="2">dry vermouth</item>
  <item quantity="7">amaretto</item>
</stock>

With this DTD:

<!-- DTD for bar stock (drink ingredients -->
 <!-- One day we should add a way to allow quantities and units to be included -->

     <!ELEMENT stock (item)*>

     <!ELEMENT item  (#PCDATA)>
     <!ATTLIST item quantity CDATA #IMPLIED>

Thanks for the help.


EDIT: I (Amir Rachum) am adding my own stacktrace to the question as I have this problem as well:

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 cs236369.hw5.servlets.xml.UploadTheme.addThemeToList(UploadTheme.java:115)
    at cs236369.hw5.servlets.xml.UploadTheme.doPost(UploadTheme.java:91)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Unknown Source)
Amir Rachum
  • 76,817
  • 74
  • 166
  • 248
JustMe
  • 289
  • 3
  • 10
  • Can you add the stack trace? I assume the error happens on `root.appendChild(item)` but I would like to be sure :) – Augusto Apr 30 '11 at 09:02
  • yes that is when I get the error the stack trace is: run: org.w3c.dom.DOMException: NO_MODIFICATION_ALLOWED_ERR: An attempt is made to modify an object where modifications are not allowed.[Ljava.lang.StackTraceElement;@4406cef4 – JustMe May 01 '11 at 06:19
  • I've been having this problem too. Any solutions? – Amir Rachum Aug 06 '11 at 14:45
  • can you add the full stacktrace to your question? – joostschouten Aug 06 '11 at 14:54

1 Answers1

3

@Amir Rachum , @JustMe:

Meaning of exception:NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly

In above code, you relied on doc.getFirstChild(); to provide you root element. Never do that, because as per DOM model, children of document are Comment, Processing Instruction, root Element. So you never know your DOM parser implementation might be giving you processing instruction or comment. Instead use following:-

 Element rootelment=document.getDocumentElement();
 //code to create a new node
rootlement.appendChild(newnode);

If you are still not sure about ur code, just print getNodeType() before calling appendChild() method on it and then look DOM specification for whether it is readonly node or not.

ag112
  • 5,537
  • 2
  • 23
  • 42