Remove multiple nodes from an xml file using sax and java

java, sax, xml

Solution

Try as

    XMLReader xr = new XMLFilterImpl(XMLReaderFactory.createXMLReader()) {
        private boolean skip;

        @Override
        public void startElement(String uri, String localName, String qName, Attributes atts)
                throws SAXException {
            if (qName.equals("rule")) {
                if (atts.getValue("id").equals("1")) {
                    skip = true;
                } else {
                    super.startElement(uri, localName, qName, atts);
                    skip = false;
                }
            } else {
                if (!skip) {
                    super.startElement(uri, localName, qName, atts);
                }
            }
        }

        public void endElement(String uri, String localName, String qName) throws SAXException {
            if (!skip) {
                super.endElement(uri, localName, qName);
            }
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            if (!skip) {
                super.characters(ch, start, length);
            }
        }
    };
    Source src = new SAXSource(xr, new InputSource("test.xml"));
    Result res = new StreamResult(System.out);
    TransformerFactory.newInstance().newTransformer().transform(src, res);

output

<?xml version="1.0" encoding="UTF-8"?><ruleset>
    <rule id="2">
        <condition>
            <case2>somefunctionality</case2>
            <allow>false</allow>
        </condition>
    </rule>
</ruleset>

Problem

I am new to XML parsing using Java and SAX parser. I have a really big XML file and because of its size I have been advised to use SAX parser. I have finished parsing part of my tasks and it works as expected. Now, there is one task left with XML job: deleting/updating some nodes upon user's request. I am able to find all tags by their names, change their `data` attributes, etc. If I am able to do these with SAX, deleting also may be possible. Sample XML describes some functionality under some case's. User's inputs are the "case"s names (`case1`, `case2`). ``` <ruleset> <rule id="1"> <condition> <case1>somefunctionality</case1> <allow>true</allow> </condition> </rule> <rule id="2"> <condition> <case2>somefunctionality</case2> <allow>false</allow> </condition> </rule> </ruleset> ``` If user wants to delete one of these cases (for example `case1`) not just `case1` tag, the complete `rule` tag must be deleted. If `case1` is to be deleted, XML will become: ``` <ruleset> <rule id="2"> <condition> <case2>somefunctionality</case2> <allow>false</allow> </condition> </rule> </ruleset> ``` My question is, can this be done using SAX? I can't use DOM or any other parser at this point. Only other option is even worse: string search. How can it be done using SaxParser?

Original source