XML校验xsi:type值无效报错,HTTP请求却正常求助
解决XSD校验xsi:type无效的问题
这个报错的核心原因很明确:你的XSD里完全没有定义listRel:Customer这个类型,而XML中的xsi:type是用来告诉校验器“这个元素的实际类型是我指定的这个类型”,校验器找不到这个类型的定义,自然会报错。至于HTTP请求能正常使用,大概率是因为接收方没有做严格的XSD校验,只是做了简单的节点解析。
下面是具体的修复步骤和完整的可工作XSD:
1. 明确命名空间关联
首先要在XSD中声明XML里用到的所有命名空间:
urn:core_namespace(对应XML里的pc前缀)作为XSD的目标命名空间urn:relationships_namespace(对应XML里的listRel前缀)作为额外的命名空间引入
2. 严谨的修复方案(基于类型继承)
最规范的方式是定义一个基类型,让Customer继承它,既保证类型兼容性,又保留扩展性:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:listRel="urn:relationships_namespace" xmlns:pc="urn:core_namespace" targetNamespace="urn:core_namespace" elementFormDefault="qualified"> <!-- 定义基类型BaseRecord,作为record元素的默认类型 --> <xs:complexType name="BaseRecord"> <xs:sequence/> <xs:attribute name="internalId" type="xs:unsignedByte" use="required" /> </xs:complexType> <!-- 在listRel命名空间下定义Customer类型,继承自BaseRecord --> <xs:complexType name="Customer"> <xs:complexContent> <xs:extension base="pc:BaseRecord"> <xs:sequence> <xs:element name="companyName" type="xs:string" /> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> <xs:element name="updateList"> <xs:complexType> <xs:sequence> <!-- record元素使用基类型,允许通过xsi:type指定派生的Customer类型 --> <xs:element maxOccurs="unbounded" name="record" type="pc:BaseRecord" /> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
3. 简化修复方案(快速适配)
如果你不需要基类型的扩展性,也可以让record元素使用xs:anyType,这样只要listRel:Customer类型存在,就能通过校验:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:listRel="urn:relationships_namespace" xmlns:pc="urn:core_namespace" targetNamespace="urn:core_namespace" elementFormDefault="qualified"> <!-- 直接定义listRel:Customer类型 --> <xs:complexType name="Customer"> <xs:sequence> <xs:element name="companyName" type="xs:string" /> </xs:sequence> <xs:attribute name="internalId" type="xs:unsignedByte" use="required" /> </xs:complexType> <xs:element name="updateList"> <xs:complexType> <xs:sequence> <!-- 使用xs:anyType允许xsi:type指定任意已定义类型 --> <xs:element maxOccurs="unbounded" name="record" type="xs:anyType" /> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
为什么这样能解决问题?
- 我们在XSD中明确声明了
listRel命名空间,并且定义了Customer类型,校验器现在能找到这个类型的定义 - 第一种方案通过基类型继承,保证了
Customer类型是record元素类型的合法派生,完全符合xsi:type的使用规范 - 第二种方案用
xs:anyType放宽了类型限制,只要xsi:type指定的类型存在就会通过校验
用上面任意一个XSD去校验你的XML,都不会再出现invalid xsi:type的报错了。
内容的提问来源于stack exchange,提问作者Anshul Srivastava
相关产品推荐
相关产品推荐

