2

I am trying to remove an element and child elements from an xml file. Specifically appender with the name Testlogging.

First this is how my xml file looks.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="null" threshold="null">

<appender class="DailyLogFileAppender" name="Testlogging">
    <param name="encoding" value="UTF-8"/>
    <param name="MaxFileSize" value="100MB"/>
    <param name="MaxBackupIndex" value="2"/>
    <param name="rootDir" value="c:\Logs"/>
    <param name="componentId" value="Testlogging"/>
    <param name="DatePattern" value="yyyyMMdd"/>
    <layout class="SyslogPatternLayout">
        <param ConversionPattern="%d{yyyy-MM-dd'T'HH:mm:ss.SSSZ} [%-5p] {%t} %c [%D] - %m%n"/>
    </layout>
</appender>

Here is my java code:

DocumentBuilderFactory dbfact = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dbfact.newDocumentBuilder();
Document d = builder.parse(xmlFile);
        XPath xp = XPathFactory.newInstance().newXPath();
        NodeList nl = (NodeList)xp.compile("//appender").evaluate(d,XPathConstants.NODESET);

        for(int i = 0; i < nl.getLength(); i++)
        {
            if(xp.compile("./@name").evaluate(nl.item(i)).equals("Testlogging"))
            {
                Node node = nl.item(i);
                node.removeChild(nl.item(i));
            }
        }

I would like to remove everything for this appender but an exception is being thrown. It's probably something simple I am missing.

Any ideas?

user1158745
  • 2,402
  • 9
  • 41
  • 60
  • What's the exception ? – Seeta Somagani Nov 05 '15 at 15:31
  • Exception in thread "AWT-EventQueue-0" org.w3c.dom.DOMException: NOT_FOUND_ERR: An attempt is made to reference a node in a context where it does not exist. – user1158745 Nov 05 '15 at 15:33
  • There seems to be the solution here - http://stackoverflow.com/questions/3719384/why-can-i-not-remove-a-child-element-ive-just-found-not-found-err. You seem to be trying to remove an element by treating it as its own child? – Seeta Somagani Nov 05 '15 at 15:35
  • Sorry I am still confused on how the code fix would work. How should my code look? – user1158745 Nov 05 '15 at 15:36

1 Answers1

6

Well you need to call removeChild on the parent node of the node you want to remove and you need to process the NodeList in reverse order (as W3C DOM collections are "live" collections that can change with any DOM manipulation (https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#td-live)) so use an approach like

    NodeList nl = (NodeList)xp.compile("//appender[@name = 'Testlogging']").evaluate(d,XPathConstants.NODESET);
    for (int i = nl.getLength() - 1; i >= 0; i--) 
    {
       nl.item(i).getParentNode().removeChild(nl.item(i));
    }
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110