SV: [jdom-interest] EntityResolver to resolve relative DTDs

Per Norrman pernorrman at
Tue Dec 16 16:46:38 PST 2003


This isn't really a JDOM question, is it? Anyway, here's an approach:

	Source xmlSource = new StreamSource(<inputstream>, <systemid>);
	Source xslSource = new StreamSource(new URL(xsl).openStream());
	TransformerFactory factory = TransformerFactory.newInstance();
	Transformer transformer = factory.newTransformer(...);

	Result result = new StreamResult(<outputstream>);
	transformer.transform(xmlSource, result);

For <inputstream>, use the one you already have in 

For <systemid>, use your desired absolute uri, or This system id will be used when resolving a
relative URI, so 
the relative URI in the XML source must exist at the location pointed to
by the
absoulte URI.

For <outputstream>, use the one you already have in 

To get the desired encoding, you can specify it in the xsl source:

<xsl:output method="xml" indent="yes" encoding="ISO-8859-1"/>

The PUBLICID is just a label. Typically, this label is used to
select a local DTD for validating the xml source and/or take specific
depending on the value. 
An EntityResolver would somehow use the PUBLICID to look up the proper
and return an InputSource. For example, I would assume that all Servlet 
containers use the PUBLICID to select local copies of the servlet config

DTD (2.2, 2.3, 2.4, etc).

The SYSTEMID is a URI. If nothing else is specified, the parser will go
and try to fetch the DTD.

Finally, I would recommend using a local copy of your DTD. Why would you
want to spend the extra burden of a networked http access, when a local
access is all it takes? You can use the same approach as above, just use
a file URI
for the <systemid> parameter, e.g. file:/path/to/myDTD.dtd. You will
also *NOT* be
dependent on the HTTP server availability.


-----Ursprungligt meddelande-----
Från: jdom-interest-admin at [mailto:jdom-interest-admin at]
För Pramodh Peddi
Skickat: den 16 december 2003 18:27
Till: jdom-interest at
Ämne: [jdom-interest] EntityResolver to resolve relative DTDs


I know there are already a few requests and responses on this topic (and
a couple of them helped me in few instances), but I couldn't get exactly
what I wanted from them. I did not clearly undetsrtand the working of
EntiryResolver. I am using Java1.4's API for Transformation.

Following is what I am doing:
My source xml (which is to be transformed) has a relative URI specified
for DTD(<!DOCTYPE FEED_DTD SYSTEM "myDTD.dtd">). I want the parser to
use an absolute URL ("", and not the
"myDTD.dtd" specified inside the source xml) for the DTD to validate the
source xml.

And this is the code I am using to do the above work:
public class SELTransformationService{

private String stylesheet;
private String fileName = null;
private String dtdURL = null;

private void transform(String metadata, String stylesheet,
ServiceRequest req, ServiceResponse res){

//System.out.println("TRANSFORM USING STRING");

try {

TransformerFactory tFactory = TransformerFactory.newInstance();

Transformer transformer = tFactory.newTransformer(new StreamSource(new

InputStream inputStream =

OutputStream outputStream =

SAXParserFactory pfactory= SAXParserFactory.newInstance();


// Get an XMLReader.

XMLReader reader = pfactory.newSAXParser().getXMLReader();

//create a resolver to resolve the DTD in the source xml

//EntityResolver resolver = new DTDResolver();

reader.setEntityResolver(new DTDResolver());

DTDResolver resolver = (DTDResolver)reader.getEntityResolver();


SAXSource source = new SAXSource(reader,

new InputSource(new InputStreamReader(inputStream)));


transformer.transform(source, new StreamResult(new
OutputStreamWriter(outputStream, "iso-8859-1")));



res.send(req.getContentObject()); + " - OBJECT SENT OUT OF TRANSFORMATION-2");

} catch (Exception ex) {

res.error(req.getContentObject(), "Exception sending message to bus.");



}//end SELTransformationService classclass DTDResolver implements
EntityResolver {

String publicId = null;

public void setPublicId(String publicId){

this.publicId = publicId;

System.out.println("Setting publicID");


public String getPublicId(){

System.out.println("Getting publicId");

return this.publicId;


public InputSource resolveEntity (String publicId, String systemId){

InputStream inputStream = null;

InputSource source = null;


System.out.println("publicID is: " + this.publicId);


URL url = new URL(this.publicId);

inputStream = url.openStream();

System.out.println("got the inputstream");

source = new InputSource(new InputStreamReader(inputStream));


System.out.println("publicId is not specified!!!");


}catch(Exception e){


return source;


}//end DTDResolver class


I am sending the publicID (which is the absolute URL i am asking the
parser to for the DTD) and using that for validation.

It is not throwing any exception, but the transformed stream doesn't
have anything except the header "<?xml version="1.0"
encoding="UTF-8"?>". The header is also not supposed to have UTF-8, it
is supposed to be "iso-8859-1". Can anyone tell me what my mistake is
and what I am missing?

And few questions about the working of EntityResolver ( I went thru the
API, but its not completely clear to me. I was wondering if I can more
clear concepts about EntityResolver):

1. What is the significance of systemID and publicID?

2. What should the InputSource return symantically?

Sorry for the long email and a bunch of questions. Hope i get some help
out of it.



To control your jdom-interest membership:

More information about the jdom-interest mailing list