Description
TheJavax. xml. parsers. documentbuilder. setentityresolver (entityresolver ER)Method specifies the entityresolver to be used to resolve entities present in the XML document to be parsed. setting this to null will result in the underlying implementation using it's own default implementation and behavior.
Declaration
Following is the declarationJavax. xml. parsers. documentbuilder. setentityresolver ()Method
public abstract void setEntityResolver(EntityResolver er)
Parameters
Return Value
This method does not return a value.
Exception
Example
For our examples to work, a XML file named student. XML is needed in our classpath. The contents of this XML are the following:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><student id="10"> <age>12</age> <name>Malik</name></student>
The following example shows the usageJavax. xml. parsers. documentbuilder. setentityresolver ()Method.
package com.tutorialspoint;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.NodeList;import org.xml.sax.EntityResolver;import org.xml.sax.InputSource;// an EntityResolver for our builder.class Resolver implements EntityResolver { public InputSource resolveEntity(String publicId, String systemId) { System.out.println(publicId); System.out.println(systemId); if (systemId.equals("")) { System.out.println("Resolving Entity..."); return null; } else { // use the default behaviour return null; } }}public class DocumentBuilderDemo { public static void main(String[] args) { // create a new DocumentBuilderFactory DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); try { // use the factory to create a documentbuilder DocumentBuilder builder = factory.newDocumentBuilder(); Resolver res = new Resolver(); builder.setEntityResolver(res); // create a new document from input stream and an empty systemId Document doc = builder.parse("Student.xml"); // get the first element Element element = doc.getDocumentElement(); // get all child nodes NodeList nodes = element.getChildNodes(); // print the text content of each child for (int i = 0; i < nodes.getLength(); i++) { System.out.println("" + nodes.item(i).getTextContent()); } } catch (Exception ex) { ex.printStackTrace(); } }}
Why?What about entityresolver? If the XML file does not meet the requirements of the XSD file during parsing, an error will be reported to terminate the parsing. In fact, this is the same effect as the following:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();factory.setValidating(false);factory.setNamespaceAware(true);SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");factory.setSchema(schemaFactory.newSchema( new Source[] {new StreamSource("contacts.xsd")}));DocumentBuilder builder = factory.newDocumentBuilder();builder.setErrorHandler(new SimpleErrorHandler());Document document = builder.parse(new InputSource("document.xml"));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();factory.setValidating(true);factory.setNamespaceAware(true);DocumentBuilder builder = factory.newDocumentBuilder();builder.setErrorHandler(new SimpleErrorHandler());Document document = builder.parse(new InputSource("document.xml"));
Now, the question is, what should I do if I want to use an external DTD file for verification?
Problem proposal:
Resolve the ejb-jar.xml that appears when the network is not connected, the resolution fails.
Problem Analysis:
We use dom for XML parsing:
Documentbuilderfactory factory = documentbuilderfactory. newinstance (); documentbuilder builder = factory. newdocumentbuilder (); // Location Point document DOC = builder. parse (File );
Due to ejb-jar.xml, there are
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
During parsing.
First, documentbuilderfactory. newinstance () creates the object of the documentbuilderfactory implementation class. It searches for the Implementation class in the following way:
1. In the system environment variable (system. getproperties (), find key = javax. xml. parsers. documentbuilderfactory
2. If 1 is not found, find the java. home \ Lib \ JAXP. properties file. If the file exists, find key = javax. xml. parsers. documentbuilderfactory in the file.
3. If 2 is not found, find the META-INF/services/javax. xml. parsers. documentbuilderfactory file in all jar packages in classpath
If none of them are found, null is returned.
If none of the above are found, use the built-in JDK implementation class:
Com.sun.org. Apache. xerces. Internal. JAXP. documentbuilderfactoryimpl
When creating a documentbuilder instance, the implementation varies according to the documentbuilderfactoryimpl.
To parse XML files normally when the network is unavailable, we can set entityresolver before using builder:
Builder. setentityresolver (New entityresolver () {public inputsource resolveentity (string publicid, string systemid) throws saxexception, ioexception {return New inputsource (New stringbufferinputstream (""); // return NULL; // The effect is still to capture the DTD from the network for verification }});
The above settings will not verify the XML file.
If verification is required, we can also set the local DTD file for verification:
builder.setEntityResolver( new EntityResolver(){ public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { if(publicId.equals("-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN")) { String dtd_uri = "C:/TEMP/ejb-jar_2_0.dtd"; return new InputSource(dtd_uri); } } );
Note: directly return NULL will still capture the DTD from the network for verification.
This is why setentityresolver is used by spring to verify the XML format.
Documentbuilder setentityresolver () method