Explorer
Explorer

Reputation: 1647

SAX parser not calling start element

I am tring to execute below code but my SAX parser is not calling the startElement method.

Below is my code:

package getTableStructure;

import java.util.List;
import java.io.*;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

import getTableStructure.DBdetails;

public class InformaticaObjectParser {
//H:/Eclipse_Workspace/GWM_SHARED_DEFINITION.XML
//H:/Eclipse_Workspace/InformaticaTableStruct/
public static void main(String[] args) {
    SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
    if (args.length == 2){
        System.out.println(args[1]);
        File opDir = new File(args[1].trim());
        if (opDir.exists() && opDir.isDirectory()){
            try {
                SAXParser saxParser = saxParserFactory.newSAXParser();
                System.out.println("Parser object created");
                MyHandler handler = new MyHandler();
                System.out.println(handler);
                saxParser.parse(new File(args[0]), handler);
                String outputDir = args[1].trim(); 
                System.out.println("I am here");
                List<DBdetails> TableList = handler.getEmpList();
                for(DBdetails db : TableList){
                    System.out.println("Table list from XML: " + TableList);
                    //BufferedWriter out = new BufferedWriter(new     FileWriter("H:/Eclipse_Workspace/TableStruct/" + tableName + ".csv"));
                    BufferedWriter out = new BufferedWriter(new FileWriter( outputDir + db.getName().trim()+"."+db.getSource().trim()+".csv"));
                        for (String k : db.dbdetail.keySet() ){
                        out.write(k+","+db.dbdetail.get(k));
                        out.newLine();
                        }
                        out.close();
                    }
                } 
                catch (ParserConfigurationException | SAXException | IOException e)     {
                    e.getMessage();
                }
            }
            else{
                System.out.println("2 arguments");
            }
        }
        else{
            System.out.println(" Number of arguments should be 2");
        }
    }
}

MY Handler:

package getTableStructure;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import getTableStructure.DBdetails;

public class MyHandler extends DefaultHandler {

    private List<DBdetails> sourceList = null;
private DBdetails table = null;
public List<DBdetails> getEmpList() {
    return sourceList;
}
boolean bSource = false;
boolean bName = false;

@Override
public void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {
    System.out.println("In MyHandler");
    System.out.println(qName);
    if (qName.equalsIgnoreCase("SOURCE")) {
        table = new DBdetails();
        String NAME = attributes.getValue("DBDNAME");
        String DbName = attributes.getValue("NAME");
        table.setName(NAME.trim());
        table.setSource(DbName.trim());
        if (sourceList == null)
            sourceList = new ArrayList<>();
    } else if (qName.equalsIgnoreCase("DBDNAME")) {
        bName = true;
    } else if (qName.equalsIgnoreCase("NAME")) {
        bSource = true;
    } else if (qName.equalsIgnoreCase("SOURCEFIELD")) {
        String details = (attributes.getValue("DATATYPE").trim()+","+attributes.getValue("PRECISION").trim()+","+attributes.getValue("SCALE").trim());
        this.table.dbdetail.put(attributes.getValue("NAME").trim(),
                details);
    }
}

@Override
public void endElement(String uri, String localName, String qName)
        throws SAXException {
    if (qName.equalsIgnoreCase("SOURCE")) {
        sourceList.add(table);
    }
}

@Override
public void characters(char ch[], int start, int length)
        throws SAXException {
    if (bName) {
        table.setName(new String(ch, start, length));
        bName = false;
    } else if (bSource) {
        table.setSource(new String(ch, start, length));
        bSource = false;
    }
}

}

Below is the XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE POWERMART SYSTEM "powrmart.dtd">
<POWERMART CREATION_DATE="06/01/2015 11:44:43" REPOSITORY_VERSION="182.91">
<REPOSITORY NAME="PB_DEV02" VERSION="182" CODEPAGE="Latin1" DATABASETYPE="Sybase">
<FOLDER NAME="PB_DEFINITIONS" GROUP="" OWNER="E466701" SHARED="SHARED" DESCRIPTION="Place all PB source/target definitions here and use shortcuts for them in other PB_* folders." PERMISSIONS="rwx---rwx" UUID="6c90f1e5-b619-48fd-8ee1-5b0b136947ea">
    <SOURCE BUSINESSNAME ="" DATABASETYPE ="Sybase" DBDNAME ="database" DESCRIPTION ="" NAME ="table_name" OBJECTVERSION ="1" OWNERNAME ="dbo" VERSIONNUMBER ="1">
        <SOURCEFIELD BUSINESSNAME ="" DATATYPE ="varchar" DESCRIPTION ="" FIELDNUMBER ="1" FIELDPROPERTY ="0" FIELDTYPE ="ELEMITEM" HIDDEN ="NO" KEYTYPE ="PRIMARY KEY" LENGTH ="0" LEVEL ="0" NAME ="Col1" NULLABLE ="NOTNULL" OCCURS ="0" OFFSET ="0" PHYSICALLENGTH ="8" PHYSICALOFFSET ="0" PICTURETEXT ="" PRECISION ="8" SCALE ="0" USAGE_FLAGS =""/>
        <SOURCEFIELD BUSINESSNAME ="" DATATYPE ="varchar" DESCRIPTION ="" FIELDNUMBER ="2" FIELDPROPERTY ="0" FIELDTYPE ="ELEMITEM" HIDDEN ="NO" KEYTYPE ="NOT A KEY" LENGTH ="0" LEVEL ="0" NAME ="col2" NULLABLE ="NULL" OCCURS ="0" OFFSET ="0" PHYSICALLENGTH ="254" PHYSICALOFFSET ="8" PICTURETEXT ="" PRECISION ="254" SCALE ="0" USAGE_FLAGS =""/>
    </SOURCE>
    ..
    ..
    ..
</FOLDER>
</REPOSITORY>
</POWERMART>

It was working perfect couple of months ago when I wrote this project but when I opened it now and trying to run the InformaticaObjectParser, it is not calling the start element method in MyHandler and the programming exists without giving any error.

Please let me know if you need any other information.

Thanks

Upvotes: 0

Views: 1122

Answers (3)

Santhosh Kumar Tekuri
Santhosh Kumar Tekuri

Reputation: 3020

you can make it work without removing DOCTYPE from xml. Simply add entity resolver which resolves dtd to empty document as shows below:

saxParser.getXMLReader().setEntityResolver(new EntityResolver(){
    public InputSource resolveEntity(String publicId,String systemId){
        return new InputSource(new ByteArrayInputStream(new byte[0]));
    }
});

Upvotes: 1

Explorer
Explorer

Reputation: 1647

Hey Guys thanks for your time. I got it. It is because of below line in xml.

<!DOCTYPE POWERMART SYSTEM "powrmart.dtd">

When I removed it, the code worked. I am not sure about the reason for it. Can somebody put some light on it?

Thanks again for your time.

Upvotes: 0

Maurice Perry
Maurice Perry

Reputation: 32831

try to override the fatalError, error, warning methods to see if there is an error in your document

public class MyHandler extends DefaultHandler {
...

    @Override
    public void fatalError(SAXParseException e) throws SAXException {
        LOG.log(Level.SEVERE, e.getMessage(), e);
        throw new SAXException(e.getMessage());
    }

    @Override
    public void error(SAXParseException e) throws SAXException {
        LOG.log(Level.SEVERE, e.getMessage(), e);
        throw new SAXException(e.getMessage());
    }

    @Override
    public void warning(SAXParseException e) throws SAXException {
        LOG.log(Level.WARNING, e.getMessage(), e);
    }
...
}

Upvotes: 1

Related Questions