Validating XML with external dtd without doctype specified in xml

Hi,

I am very new to SAX, DOM and things..but I am really pulling my hair to find the soln., I have tried to search soln but I found many people asking same question but hardly anyone was satisfactory.

My problem is that I have xml file without doctype specified in it, but I have dtd available on my system.

I have tried to set MyEntityResolver which implements EntityResolver in documentBuilder but its only getting called (resolveEntity method of MyEntirtyResolver), only when I add doctype to the xml (which is not what I want) and not when there is no doctype in the xml. I have set "factory.setValidating(true)" and I also have errorHandler in place.

But why EntityResolver is not invoked when its needed most. ie. when doctype is not available in xml ?...it complains that DOCTYPE must match root=null , which is obvious because no DOCTYPE in xml.

code is as follows:

please help me ..if anyone has any idea about this ....

Mainclass is :

publicstaticvoid main(String args[]){

Document document=null;

ErrorHandler defaultHandler=new MyDefaultHandler();

String xmlFile="note.xml";

try{

System.out.println("Starting...");

boolean validXML =true;

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

factory.setNamespaceAware(true);

factory.setValidating(true);

try{

ExternalResolver er =new ExternalResolver();

// addURL is just a method which sets string in a map to be retrieved by resolveEntiy

er.addURL("D:\\SAXnDOM\\SAXProject\\note.dtd");

DocumentBuilder builder = factory.newDocumentBuilder();

builder.setEntityResolver(er);

builder.setErrorHandler(new MyDefaultHandler());

builder.parse(new File(xmlFile));

resolveEntity of ExternalResolver is as follows:

public InputSource resolveEntity(String publicId, String systemId)

throws SAXException, IOException{

System.out.println("********resolvedEntity:" +publicId +" and "+systemId +"******");

if ( urlMap !=null && urlMap.get(systemId)!=null ){

try{

returnnew InputSource(new FileReader(systemId));

}catch (FileNotFoundException e){

System.out.println("[ERROR] Unable to load entity reference: " + systemId );

}

}

returnnull;

}

publicvoid addURL(String filePath)throws MalformedURLException{

addURL(new File(filePath).toURL());

}

publicvoid addURL(URL url){

if ( urlMap ==null ){

urlMap =new HashMap();

}

urlMap.put(url,null);

}

[4506 byte] By [Lucifera] at [2007-10-2 7:32:01]
# 1

Its working.... its working ...

problem was in resolveEntity, that stupid if condition was removed like this:

public InputSource resolveEntity(String publicId, String systemId)

throws SAXException, IOException {

System.out.println("********resolvedEntity:" +publicId +" and "+systemId +"******");

try {

return new InputSource("D:\\SAXnDOM\\SAXProject\\note.dtd");

} catch (Exception e) {

System.out.println("[ERROR] Unable to load entity reference: " + systemId );

}

return null;

}

Other change is (which I didnt like ) is that in my xml, I had written fake doctype like :

<?xml version="1.0"?>

<!DOCTYPE note SYSTEM "fakenote.dtd">

<note>

<to>Tove</to>

<from>Jani</from>

<heading>Reminder</heading>

<body>Don't forget me this weekend!</body>

<Prashant>prdfjfdj</Prashant>

</note>

in above code fakenote.dtd doesnt exist anywhere ..its just to bypass that doctype:null error.

So my guess is that EntityResolver overrides doctype in the xml and applies its own doctype (note.dtd in this case)

But new proble comes...what if i dont want to add any doctype ..not even fake in xml ?

Hope my stupid mistakes will find someone usefull..

Lucifera at 2007-7-16 21:11:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 2

Hai Lucifer,

Like u, i am also new to xml and parsing.

Well i am not getting why u want xml with out DOCTYPE.

Infact without doctype it will be not well-formed.

Use some tools to create xml file, so it will show immediatelly that it is not well-fomed. Otherwise in exlore, it don't check most of times.

.......yogesh

yogesh_ga at 2007-7-16 21:11:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 3
Well, XML without doctype ....yeah its possible when you are getting xml from database, or creating it using DOM, it may be dynamically retrieved at run type ...-L
Lucifera at 2007-7-16 21:11:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 4

I am using Xerces via the DOM level 3 Api.

Here you can use : config.setParameter("schema-location", schema). The xml does not need to have a schema (DTD) in this case. Maybe you can use this also with the JAXP api you are using. Look at the properties and features pages at the xerces apache Dom site. It has documentation about it.

**** Deneer

xmldonkey@donkeydevelopment.com

dikkydeea at 2007-7-16 21:11:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 5

Hi,

Validating XML with Schema ...its bit easy :

SAXParser saxParser=new SAXParser();

saxParser.setErrorHandler(new MyDefaultHandler());

saxParser.setFeature("http://xml.org/sax/features/validation",

true);

saxParser.setFeature("http://apache.org/xml/features/validation/schema",

true);

saxParser.setFeature("http://apache.org/xml/features/validation/schema-full-checking",

true);

saxParser.setProperty(

"http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation",

"D:\\XMLSchemaValidator\\MyXMLSCHEMAValidator\\prashant.xsd");

MyDefaultHandler myDefaultHandler = new MyDefaultHandler();

saxParser.setErrorHandler(myDefaultHandler);

saxParser.parse("D:\\XMLSchemaValidator\\MyXMLSCHEMAValidator\\prashant.xml");

and thats it..

L.

Lucifera at 2007-7-16 21:11:43 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...