Hi Gary, Richard, and All,
I am happy to let you know that I got the DTD thing working perfectly. Lot
of Thanks to all trying to help me on this problem. I had to add the
following stmt to get the basic validation working:
pfactory.setNamespaceAware(true).
Now, I even implemented the ErrorHandler to handle the Exceptions coming
from DTD validation.
But, still a couple of mysteries haunt me:
1. What is the purpose of the call source.setSystemId("myDTD11.dtd") ? Any
String in place of myDTD11.dtd works. The dtd in the xml source is
myDTD.dtd. So, I din't understand its significance.
2. I din't understand why I am using
reader.setFeature("http://xml.org/sax/features/validation", true). I just
know it din't work when I din't use it. We are anyhow using
pfactory.setValidating(true). And what else is the setFeature method used
for?
I am providing the code, hoping it would be helpful to anyone working on a
smililar thing.
************************code********************
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer(new StreamSource(new
URL(this.stylesheet).openStream()));
InputStream inputStream = getInputStream();
//create the factory
SAXParserFactory pfactory= SAXParserFactory.newInstance();
pfactory.setNamespaceAware(true);
pfactory.setValidating(true);
// Get an XMLReader.
XMLReader reader = pfactory.newSAXParser().getXMLReader();
log.debug("validating is: " + pfactory.isValidating());
//create a resolver to resolve the DTD in the source xml ONLY if
//you want to validate it against the given DTD
reader.setEntityResolver(new DTDResolver());
// Turn Validation on
try {
reader.setFeature("http://xml.org/sax/features/validation",
true);
} catch (SAXNotRecognizedException e) {
log.error(e);
} catch (SAXNotSupportedException e) {
log.error(e);
}
reader.setErrorHandler(new DTDErrorHandler());
DTDResolver resolver = (DTDResolver)reader.getEntityResolver();
//send the location of the DTD to the resolver
resolver.setDtdLocation(this.dtdURL);
SAXSource source = new SAXSource(reader,
new InputSource(new InputStreamReader(inputStream, "iso-8859-1")));
//TODO - look at this
source.setSystemId("myDTD11.dtd");
transformer.transform(source, new StreamResult(new
OutputStreamWriter(outputStream, "iso-8859-1")));
log.info("out of transform");
outputStream.close();
************************************************
Thanks again!!
Pramodh.
----- Original Message -----
From: "Pramodh Peddi" <[EMAIL PROTECTED]>
To: "Gary L Peskin" <[EMAIL PROTECTED]>; <[EMAIL PROTECTED]>
Sent: Wednesday, December 17, 2003 3:27 PM
Subject: Re: resolving DTDs while transforming
> Thanx for the response Gary.
>
> Sorry for the confusion on publicId thing. Though, I think it is right, it
> is very confusing. I fixed that.
>
> Reg'g the set and get methods in the DTDResolver class: I have to pass the
> dtd's URL (to be used as dtd) to the DTDResolver class, so that it can
> return the InputSource of that url. Thats the reason it has a get and a
set
> method for dtdLocation. I cleaned the class and used this code3, which
> doesn't work either. It still generates an empty string after transforming
> the source (as I said, its not exactly empty, it has just xml header in
> it...that too not with the intended encoding). This is my DTDesolver I am
> using right now. It is invoking the resolveEntity method of the
DTDResovler
> class.
>
> ***********************DTDResolver*******************
> class DTDResolver implements EntityResolver {
> String dtdLocation = null;
>
> public void setDtdLocation(String string){
> this.dtdLocation = string;
> System.out.println("Setting dtdURL: " + this.dtdLocation);
> }
>
> public String getDtdLocation(){
> System.out.println("Getting publicId");
> return this.dtdLocation;
> }
>
> public InputSource resolveEntity (String publicId, String systemId){
> InputStream inputStream = null;
> InputSource source = null;
> try{
> System.out.println("systemId: " + systemId);
> System.out.println("publicId: " + publicId);
> System.out.println("dtdLocation is: " + this.dtdLocation);
> if(StringUtils.isNotEmpty(this.dtdLocation)){
>
> URL url = new URL(this.dtdLocation);
>
> inputStream = url.openStream();
> System.out.println("got the inputstream");
> source = new InputSource(inputStream);
> }else{
> System.out.println("publicId is not specified!!!");
> }
> }catch(Exception e){
> e.printStackTrace();
> }
>
> return source;
>
> }
> }//end DTDResolver
> *****************************************
>
> And this is the output I am getting:
>
> --------------------------------output-------------------------------
> 15:02:55,328 INFO [STDOUT] Setting dtdLocation:
> http://localhost:8080/data/SonyDAMAs
> setMetadata.dtd
> 15:02:55,328 INFO [STDOUT] systemId:
> file:///C:/jboss-3.0.6/bin/SonyDAMAssetMet
> adata.dtd
> 15:02:55,328 INFO [STDOUT] publicId: null
> 15:02:55,328 INFO [STDOUT] dtdLocation is:
> http://localhost:8080/data/SonyDAMAs
> setMetadata.dtd
> 15:02:55,343 INFO [STDOUT] got the inputstream
> -----------------------------output---------------------------------------
-
>
> FYI: The application is running on JBoss appserver.
>
> As I said, in my previous reponse to Richard, the server is running in
> jboss/bin directory and so the systemId is being set to
> file:///C:/jboss-3.0.6/bin/SonyDAMAssetMetadata.dtd. And I am not sure how
> will the publicId be set! Will it ever be set and/or used? This is what
> makes me so uncomfortable with EntityResolver.
>
> FYI: This is the transformation code:
>
> ####################################Transformation
> code###########################
> TransformerFactory tFactory = TransformerFactory.newInstance();
>
> Transformer transformer = tFactory.newTransformer(new StreamSource(new
> URL(stylesheet).openStream()));
>
> InputStream inputStream =
> req.getContentObject().getMetadataInputStream();
> OutputStream outputStream =
> req.getContentObject().getMetadataOutputStream();
>
> SAXParserFactory pfactory= SAXParserFactory.newInstance();
> pfactory.setValidating(true);
> // Get an XMLReader.
> XMLReader reader = pfactory.newSAXParser().getXMLReader();
>
> //create a resolver to resolve the DTD in the source xml
> reader.setEntityResolver(new DTDResolver());
> DTDResolver resolver = (DTDResolver)reader.getEntityResolver();
> resolver.setDtdLocation(this.dtdURL);
>
> SAXSource source = new SAXSource(reader,
> new InputSource(new InputStreamReader(inputStream)));
> //not sure if this is right!
> //if i don't have this, it throws an exception saying it cannot find
> "SonyDAMAssetMetadata.dtd"
> source.setSystemId("SonyDAMAssetMetadata.dtd");
>
> transformer.transform(source, new StreamResult(new
> OutputStreamWriter(outputStream, "iso-8859-1")));
>
############################################################################
> #################
>
> Hope you found more info about my problem to help me better:-)!
>
> Thanks,
>
> Pramodh.
>
>