如何让XML元素的age字段复用自定义Age类型进行校验?
问题描述
需要验证以下XML文档,希望为age字段设置可复用的自定义类型:
<Person> <name>joe</name> <age>254</age> </Person>
对应的XSD文件如下:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="Age"> <xs:simpleType> <xs:restriction base="xs:integer"> <xs:minInclusive value="0" /> <xs:maxInclusive value="100" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="Person"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="age" type="Age"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
该XSD报错:Src-resolve: Cannot Resolve The Name 'Age' To A(n) 'type Definition' Component.。若将type="Age"改为type="xs:integer",XSD可用,但XML中超出范围的age值会错误地通过校验。而单独的<Age>254</Age>文档能被正确校验并报错。
补充疑问:参考XSD官方示例中,PurchaseOrderType里的shipTo直接引用USAddress类型,为什么同一schema下自己定义的Age无法被解析?
解决方案
核心错误是把元素定义当成了类型定义来引用。
你当前的XSD里,<xs:element name="Age">是定义了一个名为Age的元素,而非可复用的类型。当你在age元素里写type="Age"时,XSD解析器会寻找名为Age的类型定义,但它只找到同名元素,因此报错。
正确做法是直接定义一个命名的简单类型,而非把类型嵌套在元素里。修改后的XSD如下:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- 定义可复用的命名简单类型 --> <xs:simpleType name="AgeType"> <xs:restriction base="xs:integer"> <xs:minInclusive value="0" /> <xs:maxInclusive value="100" /> </xs:restriction> </xs:simpleType> <xs:element name="Person"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> <!-- 引用自定义的AgeType类型 --> <xs:element name="age" type="AgeType"/> </xs:sequence> </xs:complexType> </xs:element> <!-- 如果仍需要单独的Age元素,也可以引用这个类型 --> <xs:element name="Age" type="AgeType"/> </xs:schema>
修改后效果:
Person下的age字段会严格按照AgeType规则校验,254这类超出范围的值会被拦截- 单独的
<Age>254</Age>也能正常校验报错 AgeType可被其他元素或属性复用,满足需求
你提到的官方示例里,USAddress本身就是通过<xs:complexType name="USAddress">定义的命名复杂类型,因此可以直接用type="USAddress"引用,和上面的AgeType用法完全一致。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

