XSD基类型限制报错求助:派生元素不符合Elt:Elt规则
错误场景
使用Liquid Studio打开XSD文件时遇到以下错误:
Error Invalid particle derivation by restriction - 'Derived element 'http://www.saudiedi.com/schema/trfMafSts:record' is not a valid restriction of base element 'http://www.saudiedi.com/schema/sau:record' according to Elt:Elt -- NameAndTypeOK.'
相关XSD代码
主Schema文件(TRFMAFSTS.xsd)
<xsd:schema targetNamespace="http://www.saudiedi.com/schema/trfMafSts" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:trfSts="http://www.saudiedi.com/schema/trfMafSts" xmlns:cm="http://www.saudiedi.com/schema/common" xmlns:cmSts="http://www.saudiedi.com/schema/cmSts" xmlns:trfMafCm="http://www.saudiedi.com/schema/trfMafCm" xmlns:sau="http://www.saudiedi.com/schema/sau" elementFormDefault="qualified" attributeFormDefault="qualified"> <xsd:import namespace="http://www.saudiedi.com/schema/common" schemaLocation="../Common/common.xsd"/> <xsd:import namespace="http://www.saudiedi.com/schema/sau" schemaLocation="../Common/saudiedi.xsd"/> <xsd:import namespace="http://www.saudiedi.com/schema/cmSts" schemaLocation="../Common/cmSts.xsd"/> <xsd:import namespace="http://www.saudiedi.com/schema/trfMafCm" schemaLocation="trfMafCommon.xsd"/> <!-- Payload implementation --> <xsd:complexType name="overallStatusInfoType"> <xsd:sequence> <xsd:element name="status" type="trfMafCm:overallStatusType"/> <xsd:element name="originalMsgId" type="cm:reqMsgIdType"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="trfMafStatusInfoType"> <xsd:sequence> <xsd:element name="status" type="trfMafCm:transferManifestStatusType"/> <xsd:element name="errorCode" type="cmSts:errorCodeType" minOccurs="0"/> <xsd:element name="remarks" type="cmSts:statusInfoRemarksType" minOccurs="0"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="referenceSeaBLInfoType"> <xsd:sequence> <xsd:element name="seaBLSeqNo" type="cm:seaBLSeqNoType"/> <xsd:element name="status" type="trfMafCm:referenceSeaBLStatusType"/> <xsd:element name="errorCode" type="cmSts:errorCodeType" minOccurs="0"/> <xsd:element name="remarks" type="cmSts:statusInfoRemarksType" minOccurs="0"/> <xsd:element name="referenceSeaBLItemInfo" type="trfSts:referenceSeaBLItemInfoType" minOccurs="0" maxOccurs="999"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="referenceSeaBLItemInfoType"> <xsd:sequence> <xsd:element name="seaItemSeqNo" type="cm:itemSeqNoType"/> <xsd:element name="status" type="trfMafCm:referenceSeaBLItemStatusType"/> <xsd:element name="errorCode" type="cmSts:errorCodeType" minOccurs="0"/> <xsd:element name="remarks" type="cmSts:statusInfoRemarksType" minOccurs="0"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="overLoadedBLItemType"> <xsd:sequence> <xsd:element name="seaItemSeqNo" type="cm:itemSeqNoType"/> <xsd:element name="status" type="trfMafCm:overLoadedBLItemStatusType"/> <xsd:element name="errorCode" type="cmSts:errorCodeType" minOccurs="0"/> <xsd:element name="remarks" type="cmSts:statusInfoRemarksType" minOccurs="0"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="overLoadedBLItemHeaderType"> <xsd:sequence> <xsd:element name="voyageNo" type="trfMafCm:voyageNoType"/> <xsd:element name="voyageDate" type="xsd:date"/> <xsd:element name="trainManifestNo" type="trfMafCm:trainMafNoType"/> <xsd:element name="trainManifestDate" type="xsd:date"/> <xsd:element name="seaMafType" type="cm:seaMafType" fixed="1"/> <xsd:element name="seaMafDate" type="xsd:date"/> <xsd:element name="seaMafNo" type="cm:seaMafNoType"/> <xsd:element name="seaBLSeqNo" type="cm:seaBLSeqNoType"/> <xsd:element name="status" type="trfMafCm:referenceSeaBLStatusType"/> <xsd:element name="errorCode" type="cmSts:errorCodeType" minOccurs="0"/> <xsd:element name="remarks" type="cmSts:statusInfoRemarksType" minOccurs="0"/> <xsd:element name="overLoadedBLItem" type="trfSts:overLoadedBLItemType" minOccurs="0" maxOccurs="999"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="trainSetInfoType"> <xsd:sequence> <xsd:element name="trainSetInfo" type="trfMafCm:trainSetHeaderTypeSts"/> <xsd:element name="referenceSeaBLInfo" type="trfSts:referenceSeaBLInfoType" minOccurs="0" maxOccurs="999"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="trfStatusType"> <xsd:complexContent> <xsd:extension base="sau:abstractPayloadType"> <xsd:sequence> <xsd:element name="reference" type="trfMafCm:referenceTypeForTrfSts"/> <xsd:element name="overallStatusInfo" type="trfSts:overallStatusInfoType"/> <xsd:element name="trfManifestStatusInfo" type="trfSts:trfMafStatusInfoType"/> <xsd:element name="trainSetStatusInfo" type="trfSts:trainSetInfoType" minOccurs="0" maxOccurs="999"/> <xsd:element name="overLoadedBLItemStatusInfo" type="trfSts:overLoadedBLItemHeaderType" minOccurs="0" maxOccurs="9999"/> </xsd:sequence> </xsd:extension> </xsd:complexContent> </xsd:complexType> <!-- SaudiEdi Framework --> <xsd:complexType name="saudiediTrfStsType"> <xsd:complexContent> <xsd:restriction base="sau:saudiEDIType"> <xsd:sequence> <xsd:element name="record" type="sau:recordType" maxOccurs="999"/> </xsd:sequence> <xsd:attribute name="docType" use="required" fixed="MAF"/> <xsd:attribute name="id" type="sau:msgIDType" use="required"/> <xsd:attribute name="msgType" use="required" fixed="TRFSTS"/> </xsd:restriction> </xsd:complexContent> </xsd:complexType> <xsd:element name="saudiEDI" type="trfSts:saudiediTrfStsType"/> </xsd:schema>
依赖Schema文件(saudiedi.xsd)
<xs:schema targetNamespace="http://www.saudiedi.com/schema/sau" elementFormDefault="qualified" attributeFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sau="http://www.saudiedi.com/schema/sau" xmlns:cm="http://www.saudiedi.com/schema/common"> <xs:import namespace="http://www.saudiedi.com/schema/common" schemaLocation="common.xsd"/> <xs:complexType name="abstractPayloadType" abstract="true"> <xs:annotation> <xs:documentation>abstract payload for domain teams to define</xs:documentation> </xs:annotation> </xs:complexType> <xs:simpleType name="msgIDType"> <xs:restriction base="xs:string"> <xs:pattern value="\c{1,3}\d{1,14}"/> </xs:restriction> </xs:simpleType> <xs:complexType name="recordType"> <xs:sequence> <xs:element name="payload" type="sau:abstractPayloadType"/> </xs:sequence> </xs:complexType> <xs:complexType name="saudiEDIType" abstract="true" block="extension"> <xs:annotation> <xs:documentation>boilerplate for saudiedi documents</xs:documentation> </xs:annotation> <xs:sequence> <xs:element name="record" type="sau:recordType" maxOccurs="999"/> </xs:sequence> <xs:attribute name="docType" use="optional"/> <xs:attribute name="id" type="sau:msgIDType" use="optional"/> <xs:attribute name="msgType" use="optional"/> </xs:complexType> </xs:schema>
错误原因分析
这个错误的核心问题在于XSD限制派生的规则约束:当你从一个基类型通过<xsd:restriction>派生复杂类型时,派生类型中的元素必须满足「比基类型更严格或完全匹配」的约束,同时还要注意命名空间的一致性。
具体来说,基类型sau:saudiEDIType中的record元素属于命名空间http://www.saudiedi.com/schema/sau,而在派生类型trfSts:saudiediTrfStsType中,你直接引用了sau:recordType作为record元素的类型,但没有显式指定元素的命名空间归属,导致验证工具认为派生的record元素属于目标命名空间trfMafSts,和基类型的record元素(属于sau命名空间)不匹配,违反了NameAndTypeOK规则。
另外,基类型的record元素对应的recordType包含一个抽象的payload元素,在派生类型中虽然没有修改这个结构,但命名空间的不一致性触发了验证错误。
修复方案
我们需要确保派生类型中的record元素和基类型的元素在命名空间、名称和类型上完全匹配,同时可以进一步限制record内部的payload为具体的派生类型(这也是业务上的合理需求,因为抽象类型不能直接实例化)。
修改TRFMAFSTS.xsd中的saudiediTrfStsType定义如下:
<xsd:complexType name="saudiediTrfStsType"> <xsd:complexContent> <xsd:restriction base="sau:saudiEDIType"> <xsd:sequence> <!-- 显式指定record元素属于sau命名空间,同时限制内部的payload为具体的trfStatusType --> <xsd:element name="record" namespace="http://www.saudiedi.com/schema/sau"> <xsd:complexType> <xsd:sequence> <xsd:element name="payload" type="trfSts:trfStatusType"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> <xsd:attribute name="docType" use="required" fixed="MAF"/> <xsd:attribute name="id" type="sau:msgIDType" use="required"/> <xsd:attribute name="msgType" use="required" fixed="TRFSTS"/> </xsd:restriction> </xsd:complexContent> </xsd:complexType>
修复说明
- 命名空间匹配:给
record元素添加namespace="http://www.saudiedi.com/schema/sau",确保它和基类型中的record元素属于同一个命名空间,满足NameAndTypeOK的验证规则。 - 抽象类型具体化:在派生的
record元素内部,将抽象的sau:abstractPayloadType替换为具体的trfSts:trfStatusType,这样既符合XSD限制派生的规则(缩小类型范围),也解决了抽象类型无法实例化的问题。 - 属性约束强化:原有的属性
fixed和use="required"是合法的限制操作(将基类型的可选属性改为必填并固定值),这部分不需要修改。
完成修改后,重新用Liquid Studio验证XSD,错误应该会消失。
内容的提问来源于stack exchange,提问作者Geeky Omar

