  | Mailing List | | Home | | Forum Home | | JBoss - Java Application Server | | Tomcat - JSP/Servlet container | | Struts - A MVC web framework | | iText - An open source PDF Java Library | | JDOM - JDOM XML Parser | | JSP - A mailing list about Java Server Pages specification and reference | | 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 | |
Struts & Hibernate
|
|
|
  | | | Allow Xslt transformations on documents that require an | Allow Xslt transformations on documents that require an 2007-02-06 - By Dave Byrne
Back When transforming a Document using XSLTransformer that required an EntityResolver to be parsed, SAXOutputter.dtdEvents() throws an exception as it is unable to locate any dtds/entities.
Attached is a patch that adds an additional constructor to JDOMSource with an EntityResolver which is passed to the internal DocumentReader allowing the SAXOutputter to properly resolve dtds.
Patch is against cvs HEAD. Any comments are welcomed.
Thanks Dave Byrne
### Eclipse Workspace Patch 1.0 #P Jdom Index: src/java/org/jdom/transform/JDOMSource.java =================================================================== RCS file: /home/cvspublic/jdom/src/java/org/jdom/transform/JDOMSource.java,v retrieving revision 1.18 diff -u -r1.18 JDOMSource.java --- src/java/org/jdom/transform/JDOMSource.java 31 Aug 2004 04:43:48 -0000 1.18 +++ src/java/org/jdom/transform/JDOMSource.java 6 Feb 2007 15:19:58 -0000 @@ -124,6 +124,15 @@ * @(protected) #getXMLReader */ private XMLReader xmlReader = null; + + /** + * Optional entity resolver associated to the source of + * this document or <code>null</code> if no EntityResolver + * was supplied with this JDOMSource. + * + * @(protected) #buildDocumentReader() + */ + private EntityResolver resolver = null; /** * Creates a JDOM TrAX source wrapping a JDOM document. @@ -168,6 +177,24 @@ } /** + * Creates a JDOM TrAX source wrapping a JDOM element with an + * associated EntityResolver to resolve external entities. + * + * @(protected) source The JDOM Element to use as source for the + * transformations + * + * @(protected) resolver Entity resolver to use for the source + * transformation + * + * @(protected) IllegalArgumentException if<code>source</code> is + * <code>null</code> + */ + public JDOMSource(Document source, EntityResolver resolver) { + setDocument(source); + this.resolver = resolver; + } + +/** * Sets the source document used by this TrAX source. * * @(protected) source the JDOM document to use as source for the @@ -280,7 +307,7 @@ while (filter.getParent() instanceof XMLFilter) { filter = (XMLFilter)(filter.getParent()); } - filter.setParent(new DocumentReader()); + filter.setParent(buildDocumentReader()); // Read XML data from filter chain. this.xmlReader = reader; @@ -302,10 +329,25 @@ */ public XMLReader getXMLReader() { if (this.xmlReader == null) { - this.xmlReader = new DocumentReader(); + this.xmlReader = buildDocumentReader(); } return this.xmlReader; } + + /** + * Build an XMLReader to be used for the source. This will + * create a new instance of DocumentReader with an + * EntityResolver instance if available. + * + * @(protected) XMLReader reading the XML data from the source + * JDOM document with an optional EntityResolver + */ + private XMLReader buildDocumentReader() { + DocumentReader reader = new DocumentReader(); + if(resolver != null) + reader.setEntityResolver(resolver); + return reader; + } //====================================================================== === // JDOMInputSource nested class Index: src/java/org/jdom/transform/XSLTransformer.java =================================================================== RCS file: /home/cvspublic/jdom/src/java/org/jdom/transform/XSLTransformer.java,v retrieving revision 1.2 diff -u -r1.2 XSLTransformer.java --- src/java/org/jdom/transform/XSLTransformer.java 6 Feb 2004 09:28:32 -0000 1.2 +++ src/java/org/jdom/transform/XSLTransformer.java 6 Feb 2007 15:19:58 -0000 @@ -61,6 +61,7 @@ import javax.xml.transform.*; import javax.xml.transform.stream.StreamSource; import org.jdom.*; +import org.xml.sax.EntityResolver; /** * A convenience class to handle simple transformations. The JAXP TrAX classes @@ -219,7 +220,7 @@ throw new XSLTransformException("Could not perform transformation", e); } } - + /** * Transforms the given document to an output document. * @@ -228,7 +229,19 @@ * @(protected) XSLTransformException if there's a problem in the transformation */ public Document transform(Document inputDoc) throws XSLTransformException { - JDOMSource source = new JDOMSource(inputDoc); + return transform(inputDoc, null); + } + + /** + * Transforms the given document to an output document. + * + * @(protected) inputDoc input document + * @(protected) resolver entity resolver for the input document + * @(protected) transformed output document + * @(protected) XSLTransformException if there's a problem in the transformation + */ + public Document transform(Document inputDoc, EntityResolver resolver) throws XSLTransformException { + JDOMSource source = new JDOMSource(inputDoc, resolver); JDOMResult result = new JDOMResult(); try { templates.newTransformer().transform(source, result);
//Sample test exposing problem
package test.jdom;
import org.jdom.Document; import org.jdom.input.SAXBuilder; import org.jdom.output.Format; import org.jdom.output.XMLOutputter; import org.jdom.transform.XSLTransformer;
public class TestEntityResolve {
public static void main(String[] args) throws Exception { FolderEntityResolver resolver = new FolderEntityResolver("dtd"); SAXBuilder builder = new SAXBuilder(); builder.setEntityResolver(resolver); Document doc = builder.build(args[0]); XSLTransformer transformer = new XSLTransformer(args[1]);
// will fail with cvs version of jdom //Document outputDoc = transformer.transform(doc);
//will succeed with patch Document outputDoc = transformer.transform(doc, resolver);
XMLOutputter out = new XMLOutputter(Format.getPrettyFormat()); out.output(outputDoc, System.out);
}
}
// Sample entity resolver which resolves all entities to files in a folder package test.jdom;
import java.io.File; import java.io.FileInputStream; import java.io.IOException;
import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException;
public class FolderEntityResolver implements EntityResolver { private File folder;
public FolderEntityResolver(String folderStr) { this.folder = new File(folderStr); }
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { File[] files = folder.listFiles(); File srcFile = new File(systemId); for(int i = 0; i < files.length; i++) { if(files[i].getName().equals(srcFile.getName())) { return new InputSource(new FileInputStream(files[i])); } } return null; }
}
//sample xml <?xml version="1.0" encoding="UTF-8 (See http://UTF-8.ora-code.com)"?> <!DOCTYPE foo SYSTEM "foo.dtd"> <foo> <bar>&entRef;</bar> </foo>
//sample dtd <?xml version="1.0" encoding="UTF-8 (See http://UTF-8.ora-code.com)"?>
<!ENTITY entRef "" > <!--UE248 angle with down zig-zag arrow --> <!ELEMENT foo (bar) > <!ELEMENT bar (#PCDATA)>
__ ____ ____ ____ ____ ____ ____ ____ ____ ____ To control your jdom-interest membership: http://www.jdom.org/mailman/options/jdom-interest/youraddr@(protected)
|
|
 |