首页 > IT职业 > IT图书 > xml之schema
在网络传输中JSON和XML是最长用的两种数据格式,JSON的特点是短小、简单,但是除了这点以外就完全不能跟XML比了,所以涉及到配置方面还是优先考虑XML吧!
但是裸奔的XML并不好用,比如我们打出来Jar包给别人用,需要他们自己在Spring配置中添加:
功能简单的时候是没有问题的,当你做的东西比较复杂的时候就会变成:
除非在你的WILE里面写的非常清楚应用用哪个 class ,需要设置哪些 property ,哪些是必填的等等等,不然没人知道该怎么写,而更好的解决办法是编写schema来定义XML的规则!
我们在配置Spring的时候经常会这么写:
其中 http://www.springframework.org/schema/beans 就是一个命名空间,而 xmlns:beans 相当于设置了命名空间的一个代号,在使用时 beans:import 就可以表示使用该命名空间中的import元素。
可以不写 :beans 来表示默认就用该命名空间,那么配置就更简单了:
在schema中由下面三个属性来控制命名空间的行为:
targetNamespace:目标命名空间
elementFormDefault:unqualified/qualified
attributeFormDefault:unqualified/qualified
当设置 unqualified 时schema中除了根元素以外,其他的元素都是没有命名空间的,在使用的时候需要将其命名空间设置为空:
<!-- 注意这里 -->
而设置为 qualified 时schema中定义的所有元素都属于 targetNamespace 所定义的命名空间:
<!-- 看这里 -->
显然用qualified看起来更简单一些,不过也是看情况的。
完整的schema的定义如下:
在这里定义元素和属性
其目的就是配置出来一堆的 element 和 attribute 来约束XML的行为,简单来说
其中:yyy是element、xxx是属性!最简单的元素如下:
对应的配置如下:
设置type为 integer 之后会对内容进行检查,如果不是数字则报错,另外可以通过 simpleType 对其扩展来实现更复杂的限定:
向元素中添加子元素、属性之后就不是一个简单元素,而是一个复杂元素,可以用 complexType 定义其类型:
对应的XML的配置为 ,子节点的定义也很简单:
对应的XML的配置为 ,其中sequence的作用是
组中的元素以指定的顺序出现在包含元素中,每个子元素可以出现0次到任意次
当然还有其他的方式:
| 指示器 | 含义 |
|---|---|
| all | 子元素可以按照任意顺序出现,且每个子元素必须只出现一次 |
| choice | 随便添加子元素,可以使用 maxOccurs 来设置可添加子元素的数目 |
| attributeGroup | 属性组 |
| group | 元素组 |
元素的类型是非常复杂的,不同的类型之间很可能有一些定义是可以重用的,我们可以定义一些基础的类型,然后使用 extension 对其进行扩展可以得到:
其他元素的可以在 这里 查看使用方法~~
当上面这些不能满足你的需求时,可以使用 any 、 anyAttribute 来允许用户配置没有在schema中定义过的东西,然后在解析的阶段进行处理!
在Spring中定义解析需要用下面两个文件来配置(需要放在META-INF目录,Spring会自动加载):
spring.schemas :命名空间对应的schemas配置的位置
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/ ,如需转载,请注明出处,否则将追究法律责任。