boomerang061797
asked on
Using JAXP to transform XML with XSLT. Can't find DTD
Hi
I am trying to transform some xml using my xsl stylesheet. My java program uses the JAXP API and I'm using j2sdk 1.4.1_01 on Win2000. The xml, xsl, and dtd files are not in the same directory as the classes.
The xml file references a dtd file:
<!DOCTYPE nrs SYSTEM "my.dtd">
When trying to transform the xml I get the following error: "Relative URI "my.dtd"; can not be resolved without a base URI."
When I comment out the DOCTYPE line in the xml file, everything works.
What's the solution? How do I get it to find the dtd file?
I am trying to transform some xml using my xsl stylesheet. My java program uses the JAXP API and I'm using j2sdk 1.4.1_01 on Win2000. The xml, xsl, and dtd files are not in the same directory as the classes.
The xml file references a dtd file:
<!DOCTYPE nrs SYSTEM "my.dtd">
When trying to transform the xml I get the following error: "Relative URI "my.dtd"; can not be resolved without a base URI."
When I comment out the DOCTYPE line in the xml file, everything works.
What's the solution? How do I get it to find the dtd file?
ASKER
It will have to be alternative 2 since I cannot change the xml file. However, I don't see where this method is to be called. My code is only using classes from the javax.xml.transform and javax.xml.transform.stream packages. The setEntityResolver method only seems to apply to javax.xml.parsers.Document Builder or objects in the org.xml.sax.helpers package. Can you give an example of what you mean?
This is my code:
import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.stream .*;
public class TransformXML {
private Transformer transformer;
public TransformXML(Reader xslt) throws TransformerException {
Source source = new StreamSource(xslt);
TransformerFactory factory = TransformerFactory.newInst ance();
transformer = factory.newTransformer(sou rce);
}
public void transform(Reader xml, Writer writer) throws TransformerException {
Source source = new StreamSource(xml);
StreamResult result = new StreamResult(writer);
transformer.transform(sour ce, result);
}
}
This is my code:
import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.stream
public class TransformXML {
private Transformer transformer;
public TransformXML(Reader xslt) throws TransformerException {
Source source = new StreamSource(xslt);
TransformerFactory factory = TransformerFactory.newInst
transformer = factory.newTransformer(sou
}
public void transform(Reader xml, Writer writer) throws TransformerException {
Source source = new StreamSource(xml);
StreamResult result = new StreamResult(writer);
transformer.transform(sour
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I used source.setSystemId("my.dtd "); which seemed to do the trick. However, i'm not sure I know what I'm doing. What do I do if the dtd isn't in the same directory as the xml file (and not in a parent or subdirecoty)? Do I have to feed it a absolute URI of the form file://c:/.... etc. ?
That's what i'd try, yes.
1. Use a file url, e.g. SYSTEM "file:///x/y/z/my.dtd"
2. Resolve the entity yourself, i.e. call setEntityResolver() on the InputSource and handle "my.dtd" in a custom entity-resolving class