Disable XML validation based on external DTD/XSD
Asked Answered
A

1

8

Is there a way to disable XML validation based on external DTD/XSD without modifications to the source code (of the libraries that construct DocumentBuilder)? Something like setting JVM-wide defaults for DocumentBuilderFactory features, and the same for SAX?

Validation is great when editing files in IDE, but I don't need my webapp failing to start just because somelib.net went down.

I know I can specify local DTD/XSD locations, but that's an inconvenient workaround.

What are the options? I can think of two:

  • Implement my own DocumentBuilderFactory.
  • Intercept construction of Xerces's DocumentBuilderImpl and modify the features Hashtable (add http://apache.org/xml/features/nonvalidating/load-external-dtd).
Arawn answered 4/5, 2011 at 12:41 Comment(4)
I thought DocumentBuilderFactory.isValidating() defaulted to false. Do you mean entity resolving?Accessible
@Accessible right... I missed that. I'll try to re-define my question.Arawn
I Think your question may be a duplicate. For help on this question, see #2503081, or search stackoverflow for "503 DTD": stackoverflow.com/search?q=503+dtd The 503 means "too busy" or "service unavailable" which is similar to the "somelib.net went down" you're trying to code for. The solution to the 503 problems is the same as the solution to yours, I think.Fruitage
@Cheeso: Similar, but not exactly that. I want to disable validation even for libraries for which I don't have source code.Arawn
B
7

Disabling validation may not prevent a processor from fetching a DTD, as it still may do so in order to use attribute defaults etc. present in the DTD (which it will place in the tree), even if it does no actual validation against the DTD's grammar.

One technique to prevent network activity when processing an XML document is to use a "blanking resolver" like this:

import java.io.ByteArrayInputStream;
import java.io.IOException;

import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class BlankingResolver implements EntityResolver
{

    public InputSource resolveEntity( String arg0, String arg1 ) throws SAXException,
            IOException
    {

        return new InputSource( new ByteArrayInputStream( "".getBytes() ) );
    }

}

and then set this prior to processing like this:

DocumentBuilderFactory factory = DocumentBuilderFactory.
factory.setNamespaceAware( true );
builder = factory.newDocumentBuilder();
builder.setEntityResolver( new BlankingResolver() );
myDoc = builder.parse( myDocUri );
// etc.

You will then also be sure that the document being processed has not been altered by any information from the DTD.y

Baumgartner answered 23/5, 2011 at 16:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.