0

I have an xml like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<User SOURCE_NAME="PublicAssetFeed" xmlns="http://abc.e.wat.com/xml">
<Employee>
<FIELD NAME="Name" TYPE="char">Rahul</FIELD>
<FIELD NAME="Branch" TYPE="char"></FIELD>
<FIELD NAME="Unique ID" TYPE="char">12345</FIELD>
</Employee> `

I want to delete the entire line where NAME="Branch". So my final XML should look like

`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<User SOURCE_NAME="PublicAssetFeed" xmlns="http://abc.e.wat.com/xml">
<Employee>
<FIELD NAME="Name" TYPE="char">Rahul</FIELD>
<FIELD NAME="Unique ID" TYPE="char">12345</FIELD>
</Employee>
</User>`

I need to do this using Java. Above XML is stored as a String. So, I need to convert it to XML, delete the particular line and then convert back to String. I tried using XPath and I could only find the main node which is 'FIELD' using the below Java code. How do I delete the entire line where NAME="Branch"

package com.javamultiplex;
import java.io.IOException;
import java.io.StringReader;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.xml.sax.InputSource;

public class test {

    public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException, XPathExpressionException{    
        String abc="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><User SOURCE_NAME=\"PublicAssetFeed\" xmlns=\"http://abc.e.wat.com/xml\"><Employee><FIELD NAME=\"Name\" TYPE=\"char\">Rahul</FIELD><FIELD NAME=\"Unique ID\" TYPE=\"char\">12345</FIELD><FIELD NAME=\"Branch\" TYPE=\"char\"></FIELD></Employee></User>"
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
        XPath xPath = XPathFactory.newInstance().newXPath();
        InputSource sourceMasterTitle = new InputSource(new StringReader(abc.toString()));
        String expression = "//FIELD[@NAME='Branch']";;         
        Node value = (Node) xPath.evaluate(expression, sourceMasterTitle ,XPathConstants.NODE);   
        System.out.println("Main node is "+value.getNodeName());
    }
}
matesio
  • 1,584
  • 17
  • 31
Pavan Kumar
  • 129
  • 7
  • Removing a node from XML means we are removing an element from its parent. You can use the removeChild() method of the node's parent node to do that. – Kris Jul 01 '19 at 08:26
  • Looks like you were on the right path with your XPath, I don't get what problem you encountered. You printed `value.getNodeName()` which is why you had only `FIELD`, but deleting this node would probably have had the expected behaviour – Aaron Jul 01 '19 at 09:35

1 Answers1

0

XML files are both flexible and smart structures which are based on a tree structure. It would be better to design your code to traverse through nodes and delete the one you want to be removed.

An indentation can be changed, the structure of the XML file can be changed. If you have an approach like "deleting a line", your code can become obsolete.

Rather than that, you have to convert string to a Document and traverse through its nodes.

package stackoverflow;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringReader;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPathExpressionException;

import org.xml.sax.InputSource;

public class XMLTester {

    public static void main(String[] args)
            throws SAXException, IOException, ParserConfigurationException, XPathExpressionException {
        String xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                + "<User xmlns=\"http://abc.e.wat.com/xml\" SOURCE_NAME=\"PublicAssetFeed\">" + "   <Employee>"
                + "      <FIELD NAME=\"Name\" TYPE=\"char\">Rahul</FIELD>"
                + "      <FIELD NAME=\"Branch\" TYPE=\"char\" />"
                + "      <FIELD NAME=\"Unique ID\" TYPE=\"char\">12345</FIELD>" + "   </Employee>" + "</User>";

        Document doc = readStringAsDocument(xmlStr);

        try {
            printDocument(doc, System.out);
        } catch (TransformerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Node willBeDeleted = null;

        NodeList fieldNodes = doc.getElementsByTagName("FIELD");

        if (fieldNodes.getLength() > 0) {
            for (int i = 0; i < fieldNodes.getLength(); i++) {
                Node node = fieldNodes.item(i);
                NamedNodeMap attributes = node.getAttributes();

                for (int j = 0; j < attributes.getLength(); j++) {
                    Node att = attributes.item(j);

                    if (att.getNodeName().equals("NAME") && att.getNodeValue().equals("Branch")) {
                        willBeDeleted = node;
                    }
                }
            }
        }

        willBeDeleted.getParentNode().removeChild(willBeDeleted);

        try {
            printDocument(doc, System.out);
        } catch (TransformerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private static Document readStringAsDocument(String xmlString)
            throws ParserConfigurationException, SAXException, IOException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

        DocumentBuilder db = null;

        db = dbf.newDocumentBuilder();

        Document doc = db.parse(new InputSource(new StringReader(xmlString)));
        return doc;
    }

    // https://stackoverflow.com/a/2325407/2384806
    public static void printDocument(Document doc, OutputStream out) throws IOException, TransformerException {
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

        transformer.transform(new DOMSource(doc), new StreamResult(new OutputStreamWriter(out, "UTF-8")));
    }
}
mdoflaz
  • 551
  • 6
  • 19