Spring source deep analysis notes (four)

DTD and XSD difference DTD (Document Type Definition) is an XML constraint schema language, which is an authentication mechanism for XML files and is part of the composition of XML files. DTD is an effective way to ensure the correct format of XML documents. You can compare XML documents and DTD files to see if the documents conform to the specifications, and whether the elements and labels are used correctly. A DTD document contains: the definition rules of the elements, the definition rules of the relationships between the elements, the attributes that the elements can use, the attributes that can be used, or the rules of the entities. To use the DTD validation mode, you need to declare it in the header of the XML file. The following is the code that uses DTD declaration in Spring:

XML The Schema language is XSD (XML Schema Definition). XML Schema describes the structure of an XML document. An XML document can be validated with a specified XML Schema to check if the XML document meets its requirements. The document designer can specify the structure and content allowed by an XML document through XML Schema, and can check whether an XML document is valid. XML Schema itself is an XML document that conforms to the XML syntax structure. It can be parsed by a generic XML parser. In the XML Schema document to verify the XML instance document, in addition to the declaration of the namespace (xmlns=http://www.Springframework.org/schema/beans), you must also specify the storage of the XML Schema document corresponding to the namespace. position. The schema location attribute is used to specify the storage location of the XML Schema corresponding to the namespace. It consists of two parts: the URI of the namespace and the storage location or URL address of the XML Schema file identified by the namespace. After understanding the difference between DTD and XSD, it is much easier to analyze the extraction of validation patterns in Spring. Through the previous analysis, I locked the spring to get the verification mode of the corresponding resource through the getValidationModelForResource method.

protected int getValidationModeForResource(Resource resource) {
        int validationModeToUse = getValidationMode();
        //If the authentication mode is specified manually, the specified authentication mode is used 
        if (validationModeToUse != VALIDATION_AUTO) {
            return validationModeToUse;
        }
        // If not specified, the implementation of the automatic verification 
        int detectedMode = detectValidationMode(resource);
        if (detectedMode != VALIDATION_AUTO) {
            return detectedMode;
        }
        // Hmm, we didn't get a clear indication... Let's assume XSD,
        // since apparently no DTD declaration has been found up until
        // detection stopped (before finding the document's root tag).
        return VALIDATION_XSD;
    }

method is quite simple. It is nothing more than using the validation mode if the validation mode is set (can be set by calling the setValidationModel method in XmlBeanDefinitionReader), otherwise it uses automatic detection. The function of the automatic detection mode is implemented in the function detectValidationMode method. In the detectValidationMode function, the work of automatically detecting the verification mode is delegated to the special processing class XmlValidationModelDetector, and the validationModeDetector method of XmlValidataionModelDetector is called.

    protected int detectValidationMode(Resource resource) {
        if (resource.isOpen()) {
            throw new BeanDefinitionStoreException(
                    "Passed-in Resource [" + resource + "] contains an open stream: " +
                    "cannot determine validation mode automatically. Either pass in a Resource " +
                    "that is able to create fresh streams, or explicitly specify the validationMode " +
                    "on your XmlBeanDefinitionReader instance.");
        }

        InputStream inputStream;
        try {
            inputStream = resource.getInputStream();
        }
        catch (IOException ex) {
            throw new BeanDefinitionStoreException(
                    "Unable to determine validation mode for [" + resource + "]: cannot open InputStream. " +
                    "Did you attempt to load directly from a SAX InputSource without specifying the " +
                    "validationMode on your XmlBeanDefinitionReader instance?", ex);
        }

        try {
            return this.validationModeDetector.detectValidationMode(inputStream);
        }
        catch (IOException ex) {
            throw new BeanDefinitionStoreException("Unable to determine validation mode for [" +
                    resource + "]: an error occurred whilst reading from the InputStream.", ex);
        }
    }
    public int detectValidationMode(InputStream inputStream) throws IOException {
        // Peek into the file to look for DOCTYPE.
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        try {
            boolean isDtdValidated = false;
            String content;
            while ((content = reader.readLine()) != null) {
                content = consumeCommentTokens(content);
                if (this.inComment || !StringUtils.hasText(content)) {
                    continue;
                }
                if (hasDoctype(content)) {
                    isDtdValidated = true;
                    break;
                }
                if (hasOpeningTag(content)) {
                    // End of meaningful data...
                    break;
                }
            }
            return (isDtdValidated ? VALIDATION_DTD : VALIDATION_XSD);
        }
        catch (CharConversionException ex) {
            // Choked on some character encoding...
            // Leave the decision up to the caller.
            return VALIDATION_AUTO;
        }
        finally {
            reader.close();
        }
    }