Lettisha
Lettisha

Reputation: 21

Unable to delete a specific node in XML

I have an XML file and I need to delete a specific node. The node to be deleted will be defined dynamically based on the logic. I have been searching in internet for a solution but couldn't delete my node still. am getting error - NOT_FOUND_ERR: An attempt is made to reference a node in a context where it does not exist

Below is a sample XML File. I need to delete the node <NameValuePairs> which has <name>Local Variables</name>. Below is my sample XML Files Java Code

Sample XML File

<?xml version="1.0" encoding="UTF-8"?>
<DeploymentDescriptors xmlns="http://www.tibco.com/xmlns/dd">
<name>Test</name>
<version>1</version>
<DeploymentDescriptorFactory>
    <name>RepoInstance</name>
</DeploymentDescriptorFactory>
<DeploymentDescriptorFactory>
    <name>NameValuePairs</name>
</DeploymentDescriptorFactory>
<NameValuePairs>
    <name>Global Variables</name>
    <NameValuePair>
        <name>Connections1</name>
        <value>7222</value>
        <requiresConfiguration>true</requiresConfiguration>
    </NameValuePair>
    <NameValuePair>
        <name>Connections2</name>
        <value>7222</value>
        <requiresConfiguration>true</requiresConfiguration>
    </NameValuePair>
</NameValuePairs>
<NameValuePairs>
    <name>Local Variables</name>
    <NameValuePair>
        <name>Connections3</name>
        <value>8222</value>
        <requiresConfiguration>true</requiresConfiguration>
    </NameValuePair>
    <NameValuePair>
        <name>Connections3</name>
        <value>8222</value>
        <requiresConfiguration>true</requiresConfiguration>
    </NameValuePair>
</NameValuePairs>
</DeploymentDescriptors>

Java Code

File fDestFile = new File("myfile.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document oDoc3 = dBuilder.parse(fDestFile);
NodeList oDestFlowList = oDoc3.getElementsByTagName("NameValuePairs");
for (int m = 0; m < oDestFlowList.getLength(); m++) {
     NodeList oDestchildList = oDestFlowList.item(m).getChildNodes();
     for (int n = 0; n < oDestchildList.getLength(); n++) {
          Node oDestchildNode = oDestchildList.item(n);
          if ("name".equals(oDestchildNode.getNodeName())) {
             //oDestchildNode.getParentNode().removeChild(oDestchildNode);    //Not Working
             //oDoc3.getDocumentElement().removeChild(oDestchildNode); //Not Working
           }
       }
   }   
 }

Upvotes: 0

Views: 138

Answers (2)

Lettisha
Lettisha

Reputation: 21

Here is the final piece of code that finally worked

public static void main(String[] args) {
    File fXmlSubFile = new File("Sub.xml");
    File fXmlOriginalFile = new File("Original.xml");
    File fDestFile = new File("myfile.xml");
    DocumentBuilderFactory dbFactory  = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder;
    FileChannel source = null;
    FileChannel destination = null;
    XPath xPath =  XPathFactory.newInstance().newXPath();

    try{
        if (!fDestFile.exists()) {
            fDestFile.createNewFile();
        }
        source = new FileInputStream(fXmlOriginalFile).getChannel();
        destination = new FileOutputStream(fDestFile).getChannel();
        if (destination != null && source != null) {
            destination.transferFrom(source, 0, source.size());
        }
        if (source != null) {
            source.close();
        }
        if (destination != null) {
            destination.close();
        }
        dBuilder = dbFactory.newDocumentBuilder();
        Document oSubDoc = dBuilder.parse(fXmlSubFile);
        Document oDestDoc = dBuilder.parse(fDestFile);
        oSubDoc.getDocumentElement().normalize();
        oDestDoc.getDocumentElement().normalize();

         String sDestExpression = "/DeploymentDescriptors/NameValuePairs";  
         String sSubExpression = "/NameValuePairs"; 
         NodeList nodeDestList = (NodeList) xPath.compile(sDestExpression).evaluate(oDestDoc, XPathConstants.NODESET);
         NodeList nodeSubList  = (NodeList) xPath.compile(sSubExpression).evaluate(oSubDoc, XPathConstants.NODESET);
         for (int i = nodeDestList.getLength()-1; i >=0 ; i--) {
            Node oDestNode = nodeDestList.item(i);
            if (oDestNode.getNodeType() == Node.ELEMENT_NODE) {
               Element oDestElement = (Element) oDestNode;
               for (int j =0; j<nodeSubList.getLength(); j++) {
                    Node oSubNode = nodeSubList.item(j);
                    if (oSubNode.getNodeType() == Node.ELEMENT_NODE) {
                       Element oSubElement = (Element) oSubNode;
                       if(oDestElement.getElementsByTagName("name").item(0).getTextContent().equals(oSubElement.getElementsByTagName("name").item(0).getTextContent())){
                        oDestNode.getParentNode().removeChild(oDestNode);
                       }
                    }
               }
            }
         }
         Source src = new DOMSource(oDestDoc);
         Result result = new StreamResult(fDestFile);
         Transformer transformer = null;
         transformer = TransformerFactory.newInstance().newTransformer();
         // Transform your XML document (i.e. save changes to file)
         transformer.transform(src, result);
    }catch(Exception ex){
        System.out.println("error:"+ex.getMessage());
        ex.printStackTrace();
    }
}

Upvotes: 1

ghg565
ghg565

Reputation: 422

You need create a separate reference from the parent node as an Element so that you aren't referencing the node that you are removing:

File fDestFile = new File("src/myfile.xml");
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder = null;
    try {
        dBuilder = dbFactory.newDocumentBuilder();
        Document oDoc3 = null;
        oDoc3 = dBuilder.parse(fDestFile);
        NodeList oDestFlowList = oDoc3.getElementsByTagName("NameValuePairs");
        // Loop through all 'NameValuePairs'
        for (int m = oDestFlowList.getLength()-1; m >=0 ; m--) {
            NodeList oDestchildList = oDestFlowList.item(m).getChildNodes();
            // Loop through children of 'NameValuePairs'
            for (int n = oDestchildList.getLength()-1; n >=0 ; n--) {
                // Remove children if they are of the type 'name'
                if(oDestchildList.item(n).getNodeName().equals("name")){
                    oDestFlowList.item(m).removeChild(oDestchildList.item(n));
                    // For debugging
                    System.out.println(oDestchildList.item(n).getNodeName());
                }
            }
        }   
        Source source = new DOMSource(oDoc3);
        Result result = new StreamResult(fDestFile);
        Transformer transformer = null;
        transformer = TransformerFactory.newInstance().newTransformer();
        // Transform your XML document (i.e. save changes to file)
        transformer.transform(source, result);
    } catch (Exception e) {
        // Catch the exception here
        e.printStackTrace();
    }
}

If you are still having issues, then I would think that it is an issue with the node types. This was working for me before I put the check in for 'oDestchildNode.getNodeType()' but I would look at what type of node you are returning and go from there.

Upvotes: 1

Related Questions