Search code examples
javaxmlsax

Write the XML data file into a text file


I have a few XML files in one folder. I want to write the XML data file into a text file. But I don't understand how to do it. :(

Sample XML file:

<?xml version = "1.0"?>
<note>
<to> Mat </to>
<from> Tim </from>
<head> Black </head>
<body> Yellow </body>
</note>

Here is my code:

public class ReadXML extends DefaultHandler {

Boolean noteTag = false;
Boolean toTag = false;
Boolean fromTag = false;
Boolean headTag = false;
Boolean bodyTag = false;

static final String NOTE = "note";
static final String TO = "to";
static final String FROM = "from";
static final String HEAD = "head";
static final String BODY = "body";

public void read() throws Exception {

    SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();

    File folder = new File("D:\\Source Code\\NetBeans\\Java\\BGPU\\ParseXMLFile");
    File[] listOfFiles = folder.listFiles();

    for (File file : listOfFiles) {
        if (file.isFile() && file.getName().endsWith(".xml")) {
            saxParser.parse(file, this);
            System.out.println();
        }
    }
}

@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

    if (qName.equalsIgnoreCase(NOTE)) {
        noteTag = true;
    }

    if (qName.equalsIgnoreCase(TO)) {
        toTag = true;
    }

    if (qName.equalsIgnoreCase(FROM)) {
        fromTag = true;
    }

    if (qName.equalsIgnoreCase(HEAD)) {
        headTag = true;
    }

    if (qName.equalsIgnoreCase(BODY)) {
        bodyTag = true;
    }
}

@Override
public void characters(char ch[], int start, int length) throws SAXException {

    if (fromTag.equals(true)) {
        System.out.println("FROM: " + new String(ch, start, length));
        }

    if (toTag.equals(true)) {
        System.out.println("TO: " + new String(ch, start, length));
        toTag = false;
    }

    if (headTag.equals(true)) {
        System.out.println("HEAD: " + new String(ch, start, length));
        headTag = false;
    }
}

@Override
public void endElement(String uri, String localName, String qName) throws SAXException {

    if (qName.equalsIgnoreCase(NOTE)) {
        noteTag = false;
    }

    if (qName.equalsIgnoreCase(TO)) {
        toTag = false;
    }

    if (qName.equalsIgnoreCase(FROM)) {
        fromTag = false;
    }

    if (qName.equalsIgnoreCase(HEAD)) {
        headTag = false;
    }

    if (qName.equalsIgnoreCase(BODY)) {
        bodyTag = false;
    }
}

public void save(String filename) throws Exception {

}

Please help me to finish the save() method.


Solution

  • I'd recommend not using SAX, here's an example using XPath instead. You can write to a file using java.util.FileWriter.

    public class Test {
        public static void main(String[] args) throws Exception {
            BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"));
    
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse("test.xml");
            XPathFactory xPathFactory = XPathFactory.newInstance();
            writer.append(xPathFactory.newXPath().compile("//note/to").evaluate(document));
            writer.newLine();
            writer.append(xPathFactory.newXPath().compile("//note/from").evaluate(document));
            writer.newLine();
            writer.append(xPathFactory.newXPath().compile("//note/head").evaluate(document));
            writer.newLine();
            writer.append(xPathFactory.newXPath().compile("//note/body").evaluate(document));
            writer.newLine();
            writer.close();
        }
    }
    

    If you really must use SAX, here's a cleaner way of doing it

    public class ReadXml {
    
        public static void main(String[] args) throws Exception {
            new ReadXml().read();
        }
    
        public void read() throws Exception {
    
            SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
    
            File folder = new File(".");
            File[] listOfFiles = folder.listFiles();
    
            for (File file : listOfFiles) {
                if (file.isFile() && file.getName().endsWith(".xml")) {
    
                    Handler handler = new Handler();
                    saxParser.parse(file, handler);
                    save(handler, file.getName() + ".txt");
                }
            }
        }
    
        private void save(Handler handler, String filename) throws IOException {
            BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
            writer.append(handler.getFrom());
            writer.newLine();
            writer.append(handler.getTo());
            writer.newLine();
            writer.append(handler.getHead());
            writer.newLine();
            writer.append(handler.getBody());
            writer.newLine();
            writer.close();
        }
    
        private class Handler extends DefaultHandler {
    
            private StringBuilder content;
            private String to;
            private String from;
            private String body;
            private String head;
    
            @Override
            public void startElement(String uri, String localName, String qName,
                    Attributes attributes) throws SAXException {
    
                content = new StringBuilder();
            }
    
            @Override
            public void characters(char ch[], int start, int length)
                    throws SAXException {
                content.append(ch, start, length);
            }
    
            @Override
            public void endElement(String uri, String localName, String qName)
                    throws SAXException {
    
                if ("to".equals(qName)) {
                    to = content.toString();
                } else if ("from".equals(qName)) {
                    from = content.toString();
                } else if ("body".equals(qName)) {
                    body = content.toString();
                } else if ("head".equals(qName)) {
                    head = content.toString();
                }
            }
    
            public String getTo() {
                return to;
            }
    
            public String getFrom() {
                return from;
            }
    
            public String getBody() {
                return body;
            }
    
            public String getHead() {
                return head;
            }
    
        }
    }