我在尝试使用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'。预期可能元素列表:'已接受'。| Stack:0 - Xml:129;
任何建议表示赞赏。
答案 0 :(得分:1)
声明以下序列时:
<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的XML和例如Id pr Price。
在最新的情况下,您可以尝试使用xs:choice而不是xs:sequence来实现另一个xsd。但我不确定您是否可以使用不同类型的Status元素。
为了快速验证,您可以尝试免费的在线XML - XSD验证器,因为您的情况很小,您可以轻松地做到这一点。
另外,请注意序列定义: