ITPub博客

首页 > IT职业 > IT图书 > xml之schema

xml之schema

IT图书 作者:skylar 时间:2021-09-09 09:39:07 0 删除 编辑

在网络传输中JSON和XML是最长用的两种数据格式,JSON的特点是短小、简单,但是除了这点以外就完全不能跟XML比了,所以涉及到配置方面还是优先考虑XML吧!

但是裸奔的XML并不好用,比如我们打出来Jar包给别人用,需要他们自己在Spring配置中添加:

功能简单的时候是没有问题的,当你做的东西比较复杂的时候就会变成:


    
    
    

除非在你的WILE里面写的非常清楚应用用哪个 class ,需要设置哪些 property ,哪些是必填的等等等,不然没人知道该怎么写,而更好的解决办法是编写schema来定义XML的规则!

命名空间(xmlns)

我们在配置Spring的时候经常会这么写:


    

其中 http://www.springframework.org/schema/beans 就是一个命名空间,而 xmlns:beans 相当于设置了命名空间的一个代号,在使用时 beans:import 就可以表示使用该命名空间中的import元素。

可以不写 :beans 来表示默认就用该命名空间,那么配置就更简单了:


    

在schema中由下面三个属性来控制命名空间的行为:

  1. targetNamespace:目标命名空间

  2. elementFormDefault:unqualified/qualified

  3. attributeFormDefault:unqualified/qualified

当设置 unqualified 时schema中除了根元素以外,其他的元素都是没有命名空间的,在使用的时候需要将其命名空间设置为空:


    <!-- 注意这里 -->

而设置为 qualified 时schema中定义的所有元素都属于 targetNamespace 所定义的命名空间:


    <!-- 看这里 -->

显然用qualified看起来更简单一些,不过也是看情况的。

定义元素

完整的schema的定义如下:


    在这里定义元素和属性

其目的就是配置出来一堆的 element 和 attribute 来约束XML的行为,简单来说

其中:yyy是element、xxx是属性!最简单的元素如下:


对应的配置如下:

设置type为 integer 之后会对内容进行检查,如果不是数字则报错,另外可以通过 simpleType 对其扩展来实现更复杂的限定:


    
        
            
            
        
    

向元素中添加子元素、属性之后就不是一个简单元素,而是一个复杂元素,可以用 complexType 定义其类型:


    
        
    

对应的XML的配置为  ,子节点的定义也很简单:


    
        
            
            
        
    

对应的XML的配置为 12 ,其中sequence的作用是

组中的元素以指定的顺序出现在包含元素中,每个子元素可以出现0次到任意次

当然还有其他的方式:

指示器 含义
all 子元素可以按照任意顺序出现,且每个子元素必须只出现一次
choice 随便添加子元素,可以使用 maxOccurs 来设置可添加子元素的数目
attributeGroup 属性组
group 元素组

元素的类型是非常复杂的,不同的类型之间很可能有一些定义是可以重用的,我们可以定义一些基础的类型,然后使用 extension 对其进行扩展可以得到:


    
        
    
    
        
            
                
            
        
    

其他元素的可以在 这里 查看使用方法~~

当上面这些不能满足你的需求时,可以使用 any 、 anyAttribute 来允许用户配置没有在schema中定义过的东西,然后在解析的阶段进行处理!

解析

在Spring中定义解析需要用下面两个文件来配置(需要放在META-INF目录,Spring会自动加载):

  1. spring.schemas :命名空间对应的schemas配置的位置

  2. spring.handlers :命名空间对应的解析类

来看个例子:

// spring.schemashttp://www.cainiao.com/schema/easydt/easydt.xsd=META-INF/easydt.xsd// spring.handlershttp://www.cainiao.com/schema/easydt=com.cainiao.easydt.client.springTag.EasyDtNamespaceHandler

在 NamespaceHandlerSupport 中定义了遇到对应的元素的时候应该使用Parser:

public class EasyDtNamespaceHandler extends NamespaceHandlerSupport {
	public void init() {
		registerBeanDefinitionParser("easydt", new EasyDtBeanDefinitionParser());
	}}

然后用 AbstractBeanDefinitionParser 中拿到配置信息并使用 addPropertyValue 来定义BeanDefinition:

public class EasyDtBeanDefinitionParser extends AbstractSingleBeanDefinitionParser{
	protected Class getBeanClass(Element element) {
		return EasyDt.class;
	}
	protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
		builder.addPropertyValue("domain", element.getAttribute("domain"));
	}}

关于BeanDefinition的载入和解析的过程可以看 这里 ,具体的解析工作是交给 BeanDefinitionParserDelegate 来完成的,如果子元素不是简单元素可以调用 parseCustomElement 来完成解析:

builder.addPropertyValue("provider",
    parserContext.getDelegate().parseCustomElement(
        DomUtils.getChildElementByTagName(element, "provider"),
        builder.getRawBeanDefinition()));

想更灵活地在Spring中玩耍XML还是要多看看Bean的解析过程。

总结

用这些最基本的用法基本可以搞定大部分的自定义schema的需求,对于复杂的还需要深入去研究。

原文链接:http://outofmemory.cn/xml/xml-schema

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4648/viewspace-2805620/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-08-13

  • 博文量
    83
  • 访问量
    771