之前在做项目时时常需要通过一些“小xml”传输或存储一些信息,然后就在读取的时候需要先判断xml数据是否符合要求,包括这次也是这样,不同的是 这次我设计了一个比较复杂的xml,结果读取xml数据 里穿插着各种判断,洋洋洒洒写了一大坨代码。然后我就想不是有schema这种xml描述语言吗,那应该也可以在代码里用它进行校验xml…
在实现使用schema校验xml这个目标前,你首先得自己会根据自己的xml要求格式写出对应的schema,我认为写schema占实现校验目标的七成,剩下的三成才是使用代码去校验。因为一旦有schema,通过框架去校验就是一段很固定的写法了,这也就是为什么要提议使用schema,可以大大减少不必要的重复代码工作,而可以专心于读取数据处,处理关键逻辑。
xmlns:xs="http://www.w3.org/2001/XMLSchema"
显示 schema 中用到的元素和数据类型来自命名空间 “http://www.w3.org/2001/XMLSchema“。同时它还规定了来自命名空间 “http://www.w3.org/2001/XMLSchema” 的元素和数据类型应该使用前缀xs:
xmlns="http://www.runoob.com"
指出该文件的默认命名空间,在文档中所有的名字前面如果没有前缀的,就是由默认命名空间进行定义和解析的。使用默认命名空间,可以不加空间前缀。
targetNamespace="http://www.runoob.com"
标明节点下面所定义的类型都属于这个命名空间。使用targetNamespace命名空间下的元素必须要加前缀。
elementFormDefault="qualified"
表示任何xml中使用本xsd中声明的元素必须使用命名空间
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
这句话引用的这个命名空间是干什么呢(它和xmlns:xs
一样都是一个正常的引用语句,xs
,xi
都是一个别名),他和下面这句话有关:因为下面这句话需要指出你应用的命名空间的实际的文档在放在哪。这个属性就是schemaLocation,而这个属性被定义在http://www.w3.org/2001/XMLSchema-instance
中
xsi:schemaLocation="http://www.runoob.com note.xsd"
关于xmlns
和targetNamespace
的意义区分
可重用元素的使用与命名空间
xmlns与targetNamespace
关于XML Schema命名空间中已经有xmlns却还要targetnamespace的理解
我的理解:
一个元素节点添加了targetNamespace,那么这个节点以及节点之下就是用来定义这个节点。如果要用这个节点 下的元素,那么就得加上这个节点的targetNamespace,而且还必须j加上xmlns:xxx=ttt(这里的ttt代表targetNamespace,xxx代表targetNamespace的别名,然后在调用的地方使用xxx:nnn),哪怕是在这个节点之中“调用”。所以,如果你写的这个xsd并不打算让别人调用,那么就别写什么targetNamespace,这只会给你增加麻烦:自己定义的类型,同一个文件内调用还得加上命名空间,多麻烦
简易类型:
字符串类型是我们在xml里最常用的类型,但有时候 我只希望用户填写固定的某几个字符串,实现“枚举类型”,那么可以这么写
<xs:simpleType name="carType">
<xs:restriction base="xs:string">
<xs:enumeration value="Audi"/>
<xs:enumeration value="Golf"/>
<xs:enumeration value="BMW"/>
xs:restriction>
xs:simpleType>
这就实现了个简单的枚举类型,首先是string类型的,然后限定在“Audi”,“Golf”,“BMW”里面的其中一个。
下面是常用的几种对字符串限定的方式
- enumeration (布尔数据类型无法使用此约束*)
- length (布尔数据类型无法使用此约束)
- maxLength (布尔数据类型无法使用此约束)
- minLength (布尔数据类型无法使用此约束)
类型
,然后在其他地方重复引用,不要定义成元素
了 <xs:element name="product" type="prodtype"/>
<xs:complexType name="prodtype">
<xs:attribute name="prodid" type="xs:positiveInteger"/>
xs:complexType>
错误:
<xs:element name="product" type="prodtype"/>
<xs:element name="product" type="prodtype"/>
<xs:complexType>
<xs:attribute name="prodid" type="xs:positiveInteger"/>
xs:complexType>
xs:element>
设计好xml,写好schema后就可以写程序进行校验了
有个问题:xml可以用schema来校验,那schema自己的对错怎么检验呢
其实很简单,把schema粘到eclipse里就行了,对于语法上的错误,比如一开始说的那个,使用了targetNamespace,结果在下面引用了 这个schema里定义的类型,还没有加 命名空间。写到eclipse里就会报错了。当然,eclipse也只能检验语法错误,“逻辑”错误谁也没辙。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ddddd.xsd"
还记得一开始说的XMLSchema-instance里的schemaLocation
属性吗,它需要写成这样
xsi:schemaLocation="http://www.runoob.com note.xsd"
前一个值是命名空间名称,后一个才是schema所处的真正位置。而它的同胞noNamespaceSchemaLocation
从名字上就可以看出,这个不需要命名空间名称,而只需要真实地址就行了,所以我直接写上schema的位置,在eclipse里就可以“实时”看看效果了,xml格式不符合xsd要求的时候,xml就会报错。可以通过这种简单的方式对xml和schema文件进行相互检验
"35" line="17" systemID="file:///E:/workspace-jzgk/loginUtil/web-enter.xml">cvc-enumeration-valid: Value 'ID1' is not facet-valid with respect to enumeration '[ID, NAME, CLASS, LINK_TEXT, PARTIAL_LINK_TEXT, XPATH, CSS_SELECTOR]'. It must be a value from the enumeration.
"35" line="17" systemID="file:///E:/workspace-jzgk/loginUtil/web-enter.xml">cvc-type.3.1.3: The value 'ID1' of element 'fix-type' is not valid.
反馈给用户,基本已经够 一个会配置xml的人理解是什么错误了,再解释 也无非把那几个英文单词翻译一下