XSLT: Relative URI "my.dtd" can not be resolved without a base URI

P

Pavel

Greetings to all -

I'm having a problem processing xml with relative dtd URI specified
using XSLT:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mydoc SYSTEM "my.dtd">
<mydoc>
....
</mydoc>

I do not have a control over the original xml but I have my.dtd in the
app classpath. I'm getting the TransformerException: Relative URI
"my.dtd" can not be resolved without a base URI.

How do I tell to javax.xml.transform.Transformer where to find the dtd
file w/out specifying the base URI (or any other modifications of the
original xml)?

Here is how I call the xsl transformer:

// 1. Instantiate a TransformerFactory.
javax.xml.transform.TransformerFactory tFactory =
javax.xml.transform.TransformerFactory.newInstance();

// 2. Use the TransformerFactory to process the stylesheet Source and
// generate a Transformer.
javax.xml.transform.Transformer transformer =
tFactory.newTransformer(new
javax.xml.transform.stream.StreamSource(xsl));

//transformer.setURIResolver(new RelativeURIResolver());

// 3. Use the Transformer to transform an XML Source and send the
// output to a Result object.
transformer.transform(
new javax.xml.transform.stream.StreamSource(xml),
new javax.xml.transform.stream.StreamResult(out));

As you can see above, I've tried to use URIResolver() but it does not
appear to be used by the transformer to resolve the DTD.

I'm using Java(TM) 2 Runtime Environment, Standard Edition (build
1.4.2_03-b02) and default xslt processor and xml parser from there
("org.apache.xalan.processor.TransformerFactoryImpl" and
"org.apache.crimson.jaxp.DocumentBuilderFactoryImpl" I assume).

Of course, I could use java.util.regex to either remove
<!DOCTYPE[a-zA-Z0-9\". ]*> completely or to add the base url there.
But I wonder if there is more elegant solution to this.

Any suggestions are very appreciated.
Thanks
Pavel
 
D

Daniel Parker

Pavel said:
Greetings to all -

I'm having a problem processing xml with relative dtd URI specified
using XSLT:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mydoc SYSTEM "my.dtd">
<mydoc>
...
</mydoc>

I do not have a control over the original xml but I have my.dtd in the
app classpath. I'm getting the TransformerException: Relative URI
"my.dtd" can not be resolved without a base URI.

How do I tell to javax.xml.transform.Transformer where to find the dtd
file w/out specifying the base URI (or any other modifications of the
original xml)?
Hi Pavel,

Setting a custom URIResolver on the transformer won't help, since this URI
resolver is used only for resolving relative URI's passed to the XSLT
document function.

What you need to do instead is, on an XMLReader that is reading the XML
file, call the setEntityResolver method to set a custom EntityResolver.
Your custom EntityResolver needs to provide a resolveEntity method that will
do the job of substituting the absolute URL for the relative URL, see the
example of an EntityResolver in the java api docs.

So, instead of using a StreamSource to read the document, create an
XMLReader using an XMLReaderFactory, and set the EntityResolver to your
custom resolver, also create an InputSource object with the file URL, and
finally create a SAXSource object with the XMLReader and the InputSource.
That should do it.

Regards,
Daniel Parker
http://servingxml.sourceforge.net/
 
P

Peter Flynn

Pavel said:
Greetings to all -

I'm having a problem processing xml with relative dtd URI specified
using XSLT:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mydoc SYSTEM "my.dtd">
<mydoc>
...
</mydoc>

I do not have a control over the original xml but I have my.dtd in the
app classpath. I'm getting the TransformerException: Relative URI
"my.dtd" can not be resolved without a base URI.

How do I tell to javax.xml.transform.Transformer where to find the dtd
file w/out specifying the base URI (or any other modifications of the
original xml)?

The default is usually to look for the DTD in the same place as the document
instance. If you can work out where Java thinks the document is coming from,
and put the DTD in the same place (directory/pipe/stream) then it should
find it.

///Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
VetaMcRae
Top