Search code examples
javaxmlsax

How to read XML declaration with Java SAX


I want to read the XML declaration from an XML file with Java SAX. For example

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

I tried using DefaultHandler, but characters and startElement don't get called for the XML declaration. This is my code:

import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SAXStuff {
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        SAXParser sp = SAXParserFactory.newInstance().newSAXParser();
        sp.parse("test.xml", new DefaultHandler() {
            public void characters(char[] ch, int start, int length) throws SAXException {
                for(int i = start; i < start + length; i++) {
                    System.out.print(ch[i]);
                }
            }
            public void startElement(String uri, String localName, String qName, Attributes attributes)
                    throws SAXException {
                System.out.println(qName);
            }
        });
    }
}

How can I get the XML declaration using SAX in Java?


Solution

  • Since Java 14, org.xml.sax.ContentHandler has a declaration method for this purpose. DefaultHandler implements ContentHandler, so this method can be overriden to provide a custom action.

    This is the method signature:

    void declaration​(String version, String encoding, String standalone) throws SAXException
    

    version - the version string as in the input document, null if not specified
    encoding - the encoding string as in the input document, null if not specified
    standalone - the standalone string as in the input document, null if not specified

    Example:

    SAXParserFactory factory = SAXParserFactory.newInstance();
    SAXParser parser = factory.newSAXParser();
    DefaultHandler handler = new DefaultHandler(){
        @Override
        public void declaration(String version, String encoding, String standalone) {
            String declaration = "<?xml "
                    + (version != null ? "version=\"" + version + "\"": "")
                    + (encoding != null ? " encoding=\"" + encoding + "\"": "")
                    + (standalone != null ? " standalone=\"" + standalone + "\"": "")
                    + "?>";
            System.out.println(declaration);
        }
    };
    parser.parse(new File("file.xml"), handler);