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. > >