Redirecting DTD Lookups with XML EntityResolver

This article explains the role of the XML EntityResolver interface in redirecting Document Type Definition (DTD) lookups to local classpath resources. When XML parsers encounter external DTD declarations, they attempt by default to fetch these definitions over the network, introducing performance bottlenecks and security vulnerabilities. Implementing EntityResolver allows developers to intercept these external requests and provide locally bundled DTD files instead, ensuring fast, reliable, and offline-capable XML processing.

The Default Behavior of XML Parsers

When an XML parser processes an XML document with a <!DOCTYPE> declaration referencing an external SYSTEM or PUBLIC identifier (often an HTTP or HTTPS URL), the parser defaults to resolving the URI over the network. This behavior introduces significant drawbacks:

How EntityResolver Intercepts Lookups

The org.xml.sax.EntityResolver interface provides a standardized hook into the parsing lifecycle via a single method:

public InputSource resolveEntity(String publicId, String systemId);

During parsing, whenever the parser encounters an external entity or DTD reference, it passes the declared publicId and systemId to this method before attempting a network lookup:

  1. Detection: The parser passes the DTD identifier (e.g., http://example.com/dtds/schema.dtd) to resolveEntity.
  2. Matching: The custom implementation checks the identifier against known DTD names or URIs.
  3. Local Stream Retrieval: If a match occurs, the application loads the resource from the application’s classpath using ClassLoader.getResourceAsStream().
  4. InputSource Creation: The local InputStream is wrapped in an org.xml.sax.InputSource and returned to the parser.
  5. Fallback: If the entity is not recognized, returning null instructs the parser to use its default URI resolution mechanism.

Key Benefits of Classpath Redirection

Using EntityResolver to supply local DTDs provides several architectural advantages: