在.NET Core中处理XSD验证:如何在错误提示中显示字段名
问题与需求
现有一份可正常运行的XSD文件,但XML验证出错时,仅返回如下错误信息:
Validation Error: The 'FIELD' element is invalid - The value '12345' is invalid according to its datatype 'Union' - The value '12345' is not valid according to any of the memberTypes of the union.
希望错误提示中能明确包含出错FIELD元素的name属性值,方便快速定位问题字段。
原XSD文件
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:element name="DOCUMENTS"> <xs:complexType> <xs:sequence> <xs:element name="DOCUMENT"> <xs:complexType> <xs:sequence> <xs:element name="FORM" type="xs:string"/> <xs:element name="HEADER"> <xs:complexType> <xs:sequence> <xs:element name="FIELD" maxOccurs="unbounded"> <xs:complexType> <xs:simpleContent> <xs:extension base="FieldValueType"> <xs:attribute name="name" type="FieldNameType" use="required"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="TABLES" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:simpleType name="FieldNameType"> <xs:restriction base="xs:string"> <xs:enumeration value="CALC_FILE"/> <xs:enumeration value="SQL_ORGNO"/> <xs:enumeration value="SQL_RECEIVER"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="FieldValueType"> <xs:union memberTypes="CALC_FILEType SQL_ORGNOType SQL_RECEIVERType"/> </xs:simpleType> <xs:simpleType name="CALC_FILEType"> <xs:restriction base="xs:string"> <xs:pattern value="[A-Za-z ]+"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="SQL_RECEIVERType"> <xs:restriction base="xs:string"> <xs:pattern value="[A-Za-z ]+"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="SQL_ORGNOType"> <xs:restriction base="xs:string"> <xs:minLength value="5"/> <xs:maxLength value="8"/> </xs:restriction> </xs:simpleType> </xs:schema>
测试XML文件
<?xml version="1.0" encoding="utf-8"?> <DOCUMENTS> <DOCUMENT> <FORM>Development_template_DfD_1.8</FORM> <HEADER> <FIELD name="CALC_FILE">test</FIELD> <FIELD name="SQL_ORGNO">12345</FIELD> <FIELD name="SQL_RECEIVER">Test AS</FIELD> </HEADER> <TABLES /> </DOCUMENT> </DOCUMENTS>
解决方案
原XSD使用统一的联合类型FieldValueType,验证器无法将name属性与具体类型约束关联,因此错误提示无法定位到具体字段的name值。要实现需求,需使用XSD 1.1的条件类型赋值(Conditional Type Assignment),根据name属性的值为FIELD元素指定对应类型。
修改后的XSD如下:
<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1"> <xs:element name="DOCUMENTS"> <xs:complexType> <xs:sequence> <xs:element name="DOCUMENT"> <xs:complexType> <xs:sequence> <xs:element name="FORM" type="xs:string"/> <xs:element name="HEADER"> <xs:complexType> <xs:sequence> <xs:element name="FIELD" maxOccurs="unbounded"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="name" type="FieldNameType" use="required"/> </xs:extension> </xs:simpleContent> <!-- 条件类型赋值:根据name属性指定对应类型 --> <xs:alternative test="@name='CALC_FILE'" type="CALC_FILEType"/> <xs:alternative test="@name='SQL_ORGNO'" type="SQL_ORGNOType"/> <xs:alternative test="@name='SQL_RECEIVER'" type="SQL_RECEIVERType"/> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="TABLES" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:simpleType name="FieldNameType"> <xs:restriction base="xs:string"> <xs:enumeration value="CALC_FILE"/> <xs:enumeration value="SQL_ORGNO"/> <xs:enumeration value="SQL_RECEIVER"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="CALC_FILEType"> <xs:restriction base="xs:string"> <xs:pattern value="[A-Za-z ]+"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="SQL_RECEIVERType"> <xs:restriction base="xs:string"> <xs:pattern value="[A-Za-z ]+"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="SQL_ORGNOType"> <xs:restriction base="xs:string"> <xs:minLength value="5"/> <xs:maxLength value="8"/> </xs:restriction> </xs:simpleType> </xs:schema>
修改说明
- 声明XSD版本为1.1:添加命名空间和版本约束,确保支持条件类型赋值特性。
- 移除原联合类型
FieldValueType,将FIELD的基础类型改为xs:string。 - 添加
xs:alternative节点,根据name属性的不同值绑定对应的约束类型。
效果
使用修改后的XSD验证原XML时,错误提示会包含出错FIELD的name属性值,例如:
Validation Error: The value '12345' of element 'FIELD' with name attribute 'SQL_ORGNO' is invalid - The value '12345' does not match the pattern '[A-Za-z ]+'
这样就能直接定位到具体的出错字段。
内容的提问来源于stack exchange,提问作者mrd
相关产品推荐
相关产品推荐

