1

I need to parse a bunch of incoming XML documents but it does not contain DOCTYPE (they all have the different DTD). DTD is created by myself. How can I validate an XML file against a DTD that is stored locally as a file? I have following requirement:

  1. All DTDs (for different XML) Will be load into memory once,when incoming XML comes don't looked into an locally stored area.
  2. validate incoming XML on the basis of load DTD file.

Thanks

1
  • 2
    It seems duplicated question "Validate an XML file against local DTD file with Java" Commented Feb 28, 2011 at 10:28

1 Answer 1

1

You need to use a local entity resolver on your SAX parser, here is an example of how to implement it:

class LocalEntityResolver implements EntityResolver {

private static final Logger LOG = ESAPI.getLogger(LocalEntityResolver.class);
private static final Map<String, String> DTDS;
static {
    DTDS = new HashMap<String, String>();
    DTDS.put("-//W3C//DTD XHTML 1.0 Transitional//EN",
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd");
    DTDS.put("-//W3C//ENTITIES Latin 1 for XHTML//EN",
            "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent");
    DTDS.put("-//W3C//ENTITIES Symbols for XHTML//EN",
            "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent");
    DTDS.put("-//W3C//ENTITIES Special for XHTML//EN",
            "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent");
}

@Override
public InputSource resolveEntity(String publicId, String systemId)
        throws SAXException, IOException {
    InputSource input_source = null;
    if (publicId != null && DTDS.containsKey(publicId)) {
        LOG.debug(Logger.EVENT_SUCCESS, "Looking for local copy of [" + publicId + "]");

        final String dtd_system_id = DTDS.get(publicId);
        final String file_name = dtd_system_id.substring(
                dtd_system_id.lastIndexOf('/') + 1, dtd_system_id.length());

        InputStream input_stream = FileUtil.readStreamFromClasspath(
                file_name, "your/dtd/location",
                getClass().getClassLoader());
        if (input_stream != null) {
            LOG.debug(Logger.EVENT_SUCCESS, "Found local file [" + file_name + "]!");
            input_source = new InputSource(input_stream);
        }
    }

    return input_source;
}
}
Sign up to request clarification or add additional context in comments.

1 Comment

oh and then you would use it like this DocumentBuilder builder = DocumentBuilderFactory .newInstance().newDocumentBuilder(); builder.setEntityResolver(new LocalEntityResolver()); document = builder.parse(is);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.