Spring源码导读之xml基础知识

xml基础知识

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        ">


</beans>

java提供的xml解析工具有:sax/dom/dom4j。Spring用的是dom。

schema,提要,纲要; 用于定义元素和属性的层次结构。

xmlns: xml, name space 名称空间,用于确定标签的一致性。如上面的xmlns="http://www.springframework.org/schema/beans"描述的是beans这个标签的名称空间。

xmlns:xsi=,业界默认的用于XSD(XML Schama Definition)文件的命名空间。业界还有一种校验方式是DTD。

xsi:schamaLocation,以key+value的形式,代表key这个名称空间的schema文件在value这个地方。上面案例表示的意思是<beans> 这个标签的schema文件在http://www.springframework.org/schema/beans/spring-beans-3.1.xsd

下面代码可以开启对名称空间的校验:

factory.setNamespaceAware(true);
        factory.setValidating(true);
        // 开启校验这个是必须加的常量
        factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");

案例:对这个文件xml_parse_demo.xml进行解析

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.1.xsd
        ">
    <context:component-scan base-package="com"/>
    <bean class="com.jack.postprocessor.Test">
        <property name="mapperScanPostProcessor"/>
    </bean>
    <bean class="com.jack.postprocessor.ModelService" />
</beans>

解析代码:

public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException {
        ClassPathResource resource = new ClassPathResource("xml_parse_demo.xml");
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        factory.setValidating(true);
        // 开启校验这个是必须加的常量
        factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");

        DocumentBuilder documentBuilder = factory.newDocumentBuilder();

        // 设置如果 schema无法联网情况下加载本地schema
        documentBuilder.setEntityResolver((publicId, systemId) -> {
            System.out.println(systemId);
            if (systemId.equals("http://www.springframework.org/schema/beans/spring-beans-3.1.xsd")) {
                ClassPathResource schama = new ClassPathResource("org/springframework/beans/factory/xml/spring-beans.xsd");
                InputSource inputSource = new InputSource(schama.getInputStream());
                inputSource.setSystemId(systemId);
                return inputSource;
            } else if(systemId.equals("http://www.springframework.org/schema/context/spring-context-3.1.xsd")) {
                ClassPathResource schama = new ClassPathResource("org/springframework/context/config/spring-context.xsd");
                InputSource inputSource = new InputSource(schama.getInputStream());
                inputSource.setSystemId(systemId);
                return inputSource;
            } else if (systemId.equals("http://www.springframework.org/schema/tool/spring-tool.xsd")) {
                ClassPathResource schama = new ClassPathResource("org/springframework/beans/factory/xml/spring-tool.xsd");
                InputSource inputSource = new InputSource(schama.getInputStream());
                inputSource.setSystemId(systemId);
                return inputSource;
            }
            return null;
        });
        // 设置校验xml时的处理者
        documentBuilder.setErrorHandler(new ErrorHandler() {
            @Override
            public void warning(SAXParseException exception) throws SAXException {
                System.out.println(exception.toString());
            }
            @Override
            public void error(SAXParseException exception) throws SAXException {
                throw exception;
            }
            @Override
            public void fatalError(SAXParseException exception) throws SAXException {
                throw exception;
            }
        });
        // 解析xml
        Document document = documentBuilder.parse(resource.getInputStream());
        Element root = document.getDocumentElement();
        System.out.println(root.getNodeName());
        String tab = "";
        parse(root, tab + "\t");
    }

    // 模拟对xml的解析
    public static void parse(Node node, String tab) {
        NodeList childNodes = node.getChildNodes();
        int len = childNodes.getLength();
        for (int i = 0; i < len; i++) {
            Node childNode = childNodes.item(i);
            if (childNode instanceof Element) {
                System.out.println(tab + childNode.getNodeName());
                parse(childNode, tab + "\t");
            }

        }
    }

我们配置的schema文件是网络文件,如果不联网的情况需要将网络文件替换为本地文件,Spring的schema本地文件的替换信息都配置在META-INF/spring.schemas的文件里面:

 

 

org.springframework.beans.factory.xml.ResourceEntityResolver#resolveEntity

public InputSource resolveEntity(String publicId, @Nullable String systemId) throws SAXException, IOException {
		InputSource source = super.resolveEntity(publicId, systemId);
		if (source == null && systemId != null) {
			String resourcePath = null;
			try {
				String decodedSystemId = URLDecoder.decode(systemId, "UTF-8");
				String givenUrl = new URL(decodedSystemId).toString();
				String systemRootUrl = new File("").toURI().toURL().toString();
				// Try relative to resource base if currently in system root.
				if (givenUrl.startsWith(systemRootUrl)) {
					resourcePath = givenUrl.substring(systemRootUrl.length());
				}
			}
			catch (Exception ex) {
				// Typically a MalformedURLException or AccessControlException.
				if (logger.isDebugEnabled()) {
					logger.debug("Could not resolve XML entity [" + systemId + "] against system root URL", ex);
				}
				// No URL (or no resolvable URL) -> try relative to resource base.
				resourcePath = systemId;
			}
			if (resourcePath != null) {
				if (logger.isTraceEnabled()) {
					logger.trace("Trying to locate XML entity [" + systemId + "] as resource [" + resourcePath + "]");
				}
				Resource resource = this.resourceLoader.getResource(resourcePath);
				source = new InputSource(resource.getInputStream());
				source.setPublicId(publicId);
				source.setSystemId(systemId);
				if (logger.isDebugEnabled()) {
					logger.debug("Found XML entity [" + systemId + "]: " + resource);
				}
			}
		}
		return source;
	}
private Map<String, String> getSchemaMappings() {
		Map<String, String> schemaMappings = this.schemaMappings;
		if (schemaMappings == null) {
			synchronized (this) {
				schemaMappings = this.schemaMappings;
				if (schemaMappings == null) {
					if (logger.isDebugEnabled()) {
						logger.debug("Loading schema mappings from [" + this.schemaMappingsLocation + "]");
					}
					try {
						Properties mappings =
								PropertiesLoaderUtils.loadAllProperties(this.schemaMappingsLocation, this.classLoader);
						if (logger.isDebugEnabled()) {
							logger.debug("Loaded schema mappings: " + mappings);
						}
						schemaMappings = new ConcurrentHashMap<>(mappings.size());
						CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings);
						this.schemaMappings = schemaMappings;
					}
					catch (IOException ex) {
						throw new IllegalStateException(
								"Unable to load schema mappings from location [" + this.schemaMappingsLocation + "]", ex);
					}
				}
			}
		}
		return schemaMappings;
	}

java copy on write

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值