   | Mailing List | | Home | | Forum Home | | JBoss - Java Application Server | | Struts - A MVC web framework | | Tomcat - JSP/Servlet container | | iText - An open source PDF Java Library | | JDOM - JDOM XML Parser | | J2EE - A mailing list for Java(tm) 2 Platform, Enterprise Edition | | J2EE Pattern - An interest list for Sun Java Center J2EE Pattern Catalog | | Servlet - A mailing list for discussion about Sun Microsystem's Java Servlet API Technology | | JSP - A mailing list about Java Server Pages specification and reference | |
Struts & Hibernate
|
|
|
  | |  | SV: [jdom-interest] EntityResolver to resolve relative DTDs | SV: [jdom-interest] EntityResolver to resolve relative DTDs 2003-12-16 - By Per Norrman
Back Hi,
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 req.getContentObject().getMetadataInputStream().
For <systemid>, use your desired absolute uri, http://myserver.com/dtd/myDTD.dtd or http://myserver.com/. 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 req.getContentObject().getMetadataOutputStream().
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 actions depending on the value. An EntityResolver would somehow use the PUBLICID to look up the proper DTD 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 there 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 file 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.
/pmn
-- --Ursprungligt meddelande-- -- Fr?n: jdom-interest-admin@(protected) [mailto:jdom-interest-admin@(protected)] F?r Pramodh Peddi Skickat: den 16 december 2003 18:27 Till: jdom-interest@(protected) ?mne: [jdom-interest] EntityResolver to resolve relative DTDs
Hi,
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 ("http://myserver.com/dtd/myDTD.dtd", 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: **********************************CODE********************************** **** ****************** 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 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
//EntityResolver resolver = new DTDResolver();
reader.setEntityResolver(new DTDResolver());
DTDResolver resolver = (DTDResolver)reader.getEntityResolver();
resolver.setPublicId(this.dtdURL);
SAXSource source = new SAXSource(reader,
new InputSource(new InputStreamReader(inputStream)));
source.setSystemId("SonyDAMAssetMetadata.dtd");
transformer.transform(source, new StreamResult(new OutputStreamWriter(outputStream, "iso-8859-1")));
outputStream.close();
req.getContentObject().commit();
res.send(req.getContentObject());
log.info(fileName + " - OBJECT SENT OUT OF TRANSFORMATION-2");
} catch (Exception ex) {
res.error(req.getContentObject(), "Exception sending message to bus.");
ex.printStackTrace();
}
}//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;
try{
System.out.println("publicID is: " + this.publicId);
if(StringUtils.isNotEmpty(this.publicId)){
URL url = new URL(this.publicId);
inputStream = url.openStream();
System.out.println("got the inputstream");
source = new InputSource(new InputStreamReader(inputStream));
}else{
System.out.println("publicId is not specified!!!");
}
}catch(Exception e){
}
return source;
}
}//end DTDResolver class
******************************************************CODE************** **** *****************************
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.
Thanks,
Pramodh.
__ ____ ____ ____ ____ ____ ____ ____ ____ ____ To control your jdom-interest membership: http://lists.denveronline.net/mailman/options/jdom-interest/youraddr@(protected) rhost.com
__ ____ ____ ____ ____ ____ ____ ____ ____ ____ To control your jdom-interest membership: http://lists.denveronline.net/mailman/options/jdom-interest/youraddr@(protected) .com
Earn $52 per hosting referral at Lunarpages.
|
|
 |