XSD设置complexType abstract="true"引发XML验证错误求助
问题描述
您好!@Yitzhak Khabinsky,我复制了一个小示例如下:
XSD文件定义
<?xml version="1.0"?> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1" > <xs:element name="CalculationProcess"> <xs:complexType> <xs:sequence> <xs:element name="CalculationStep" type="CalculationStepType" minOccurs="1" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType> <xs:unique name="UniqueId"> <xs:selector xpath="CalculationStep"/> <xs:field xpath="@Id" /> </xs:unique> </xs:element> <xs:complexType name="CalculationStepType"> <xs:sequence> <xs:element name="Parameter"> <xs:complexType> <xs:all> <xs:element name="AdditionalData" type="AddData" minOccurs="0"> <xs:alternative test="@Type = 'Woodham'" type="AddDataWoodham"/> </xs:element> </xs:all> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="Id" use="required" inheritable="true"> <xs:simpleType> <xs:restriction base="xs:integer"> <xs:minInclusive value="0"></xs:minInclusive> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="Name" type="xs:string" use="required" inheritable="true" /> <xs:attribute name="Type" type="TCalculationStepType" use="required" /> <xs:attribute name="InputCount" type="xs:integer" use="required" /> <xs:attribute name="OutputCount" type="xs:integer" use="required" /> <!-- StreamId must > 0 --> <xs:attribute name="StreamId" use="required" > <xs:simpleType> <xs:restriction base="xs:integer"> <xs:minInclusive value="1"></xs:minInclusive> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> <!-- CalculationStep@Type must match one of the enumerations --> <xs:simpleType name="TCalculationStepType"> <xs:restriction base="xs:string"> <xs:enumeration value="Woodham" /> </xs:restriction> </xs:simpleType> <xs:complexType name="AddData" abstract="true"/> <xs:complexType name="AddDataWoodham"> <xs:complexContent> <xs:extension base="AddData"> <!--PhotostereoWoodham--> <xs:all> <xs:element name="FilePath" type="xs:string" minOccurs="1" /> <xs:element name="ScaleFactorP" type="xs:decimal" minOccurs="1" /> <xs:element name="ScaleFactorQ" type="xs:decimal" minOccurs="1" /> <xs:element name="CalculationMethod" type="xs:integer" minOccurs="1" /> <xs:element name="SlantLookupSize" type="xs:integer" minOccurs="1" /> <xs:element name="TiltLookupSize" type="xs:integer" minOccurs="1" /> </xs:all> </xs:extension > </xs:complexContent> </xs:complexType> </xs:schema>
XML文件
<?xml version='1.0'?> <CalculationProcess xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ObjCalcConfig.xsd"> <CalculationStep Id='0' Name='Woodham' Type='Woodham' InputCount='4' OutputCount='3' StreamId='1'> <Parameter> <AdditionalData> <FilePath>files\matrix.xml</FilePath> <ScaleFactorP>1.5</ScaleFactorP> <ScaleFactorQ>1.5</ScaleFactorQ> <CalculationMethod>2</CalculationMethod> <SlantLookupSize>25</SlantLookupSize> <TiltLookupSize>72</TiltLookupSize> </AdditionalData> </Parameter> </CalculationStep> </CalculationProcess>
遇到的错误
验证报错:元素AdditionalData属于抽象类型AddData,无法直接实例化;同时XSD中定义的xs:alternative规则要求AdditionalData存在Type属性,但XML中该元素未包含此属性,导致无法触发类型切换。
我尝试将abstract设为"false",但由于基元素为空,这也不起作用……恳请帮忙解决该错误,非常感谢!
解决方案
问题根源
- 抽象类型实例化违规:
AddData被定义为抽象类型(abstract="true"),XML中直接使用<AdditionalData>属于实例化抽象类型,违反XSD约束规则。 xs:alternative条件不满足:XSD中AdditionalData的xs:alternative规则测试@Type = 'Woodham',但XML里的AdditionalData没有Type属性,无法触发类型切换到AddDataWoodham。
修复方案
方案一:给XML的AdditionalData添加Type属性
修改XML中的<AdditionalData>元素,补充Type="Woodham"属性,这样xs:alternative会触发类型切换,同时避免实例化抽象类型:
<AdditionalData Type="Woodham"> <FilePath>files\matrix.xml</FilePath> <ScaleFactorP>1.5</ScaleFactorP> <ScaleFactorQ>1.5</ScaleFactorQ> <CalculationMethod>2</CalculationMethod> <SlantLookupSize>25</SlantLookupSize> <TiltLookupSize>72</TiltLookupSize> </AdditionalData>
方案二:调整XSD的xs:alternative测试条件(基于父元素属性)
如果希望根据CalculationStep的Type属性来切换AdditionalData的类型,可以修改XSD中xs:alternative的test表达式,指向父元素的属性:
<xs:element name="AdditionalData" type="AddData" minOccurs="0"> <xs:alternative test="../@Type = 'Woodham'" type="AddDataWoodham"/> </xs:element>
这种情况下XML不需要给AdditionalData加Type属性,验证时会根据父元素CalculationStep的Type="Woodham"自动应用AddDataWoodham类型。
方案三:移除抽象类型限制(不推荐)
如果不需要抽象类型的约束,可以删除AddData的abstract="true",但这样会允许空的AdditionalData元素,不符合业务逻辑,因此不推荐。
内容的提问来源于stack exchange,提问作者Anonyme mein Name geht Dich n
相关产品推荐
相关产品推荐

