使用XSD反序列化字符串时出现问题
本文关键字:问题 字符串 XSD 反序列化 使用 | 更新日期: 2023-09-27 18:27:52
我在尝试使用XSD取消序列化XML字符串时遇到问题。我正在使用c#/Asp.Net和DataContractSerializer。
这是从第三方返回的字符串:
<ApplicationResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Id>11625807</Id>
<Status>Declined</Status>
<Response>1</Response>
<Price />
<Detail>No Qualified Buyers Found</Detail>
</ApplicationResponse>
这是我试图创建的类:
[DataContract(Name = "ApplicationResponse", Namespace = "")]
public class SCFResponse
{
[DataMember]
public string Id { get; set; }
[DataMember]
public string Status { get; set; }
[DataMember]
public string Response { get; set; }
[DataMember]
public decimal Price { get; set; }
[DataMember]
public string Detail { get; set; }
}
在我尝试根据XSD进行验证之前,一切都很好。我不是这里的专家,所以这可能很简单。
顺便说一句,我试图实现的,也许是错误的,是根据"接受"、"拒绝"或"拒绝"的子部分之一进行验证
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="ApplicationResponse" type="root"/>
<xs:complexType name="root">
<xs:sequence>
<xs:element name="accepted" type="acceptedLead"/>
<xs:element name="declined" type="declinedLead"/>
<xs:element name="rejected" type="rejectedLead"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="acceptedLead">
<xs:sequence>
<xs:element name="Id" type="id"/>
<xs:element name="Status" type="acceptedStatus"/>
<xs:element name="Price" type="price"/>
<xs:element name="Detail" type="url"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="declinedLead">
<xs:sequence>
<xs:element name="Id" type="id"/>
<xs:element name="Status" type="declinedStatus"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="rejectedLead">
<xs:sequence>
<xs:element name="Status" type="rejectedStatus"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="acceptedStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="Accepted"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="declinedStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="Declined"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="rejectedStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="Rejected"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="id">
<xs:restriction base="xs:string">
<xs:enumeration value="([0-9])+"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="price">
<xs:restriction base="xs:decimal">
<xs:minInclusive value="0.00"/>
<xs:maxInclusive value="100.00"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="url">
<xs:restriction base="xs:anyURI">
<xs:pattern value="https://.+" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
这是我正在记录的消息:
元素"ApplicationResponse"具有无效的子元素"Id"。需要可能元素的列表:"accepted"|堆栈:0-Xml:129;
如有任何建议,不胜感激。
当您声明以下序列时:
<xs:complexType name="root">
<xs:sequence>
<xs:element name="accepted" type="acceptedLead"/>
<xs:element name="declined" type="declinedLead"/>
<xs:element name="rejected" type="rejectedLead"/>
</xs:sequence>
</xs:complexType>
这意味着您期望的XML类似于:
<ApplicationResponse ...>
<accepted>...</accepted>
<declined>...</declined>
<rejected>...</rejected>
</ApplicationResponse>
您应该尝试将类型合并为一个,因为它们使用相同的标记,有时是可选的。为此,您必须去掉3种不同的枚举简单类型:
<xs:complexType name="root">
<xs:element name="Id" type="id" minOccurs="0"/>
<xs:element name="Status" type="statusEnum"/>
<xs:element name="Price" type="price" minOccurs="0"/>
<xs:element name="Detail" type="url" minOccurs="0"/>
</xs:complexType>
...
<xs:simpleType name="statusEnum">
<xs:restriction base="xs:string">
<xs:enumeration value="Accepted"/>
<xs:enumeration value="Declined"/>
<xs:enumeration value="Rejected"/>
</xs:restriction>
</xs:simpleType>
这将验证您的输入,但它仍然允许Status=rejected和Id pr Price的XML。
在这个最新的例子中,您可以尝试使用xs:choice而不是xs:sequence来实现另一个xsd。但我不确定是否可以将Status元素与不同类型一起使用。
为了快速验证,您可以尝试一个免费的在线XML-XSD验证器,因为您的情况很小,您可以轻松地做到这一点。
此外,在序列定义中要小心:
- XSD中的价格不能为空
- Detail simpleType与您的示例不匹配(https://…)
- XSD中没有详细的响应类型