使用 XSD 反序列化字符串时出现问题 [英] Having issue deserializing string with XSD

查看:25
本文介绍了使用 XSD 反序列化字符串时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在尝试使用 XSD 反序列化 XML 字符串时遇到问题.我正在使用 c#/Asp.Net 和 DataContractSerializer.

I'm having trouble trying to deserialise an XML string using an XSD. I'm using c#/Asp.Net along with the DataContractSerializer.

这是从第三方返回的字符串:

Here's the string as it's returned from a third party:

<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 进行验证.我不是这里的专家,所以这可能很简单.

It all works fine until I try to validate against my XSD. I'm not an expert here so it's probably something simple.

顺便说一句,我试图实现的,也许是错误的,是针对接受、拒绝"或拒绝"子部分之一进行验证.

Incidentally what, I'm trying to achieve, and maybe incorrectly, is to validate against one of the "accepted, "declined" or "rejected" subparts.

<?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>

这是我正在记录的消息:

Here's the message I'm logging:

元素ApplicationResponse"具有无效的子元素Id".预期的可能元素列表:已接受".|堆栈:0 - Xml:129;

The element 'ApplicationResponse' has invalid child element 'Id'. List of possible elements expected: 'accepted'.|Stack: 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 类似于:

that means your expected XML is something like:

<ApplicationResponse ...>
    <accepted>...</accepted>
    <declined>...</declined>
    <rejected>...</rejected>
</ApplicationResponse>

您应该尝试将类型合并为一个,因为它们使用相同的标签,有时是可选的.为此,您必须摆脱 3 种不同的枚举简单类型:

You should rather try to merge the types in one, as they use the same tags, sometimes optional. For this you have to get rid of the 3 different enumeration simple-types:

<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.

This will validate your input, but it will still allow XML with Status=rejected and an Id pr Price for instance.

在这种最新情况下,您可以尝试使用 xs:choice 而不是 xs:sequence 来实现另一个 xsd.但我不确定您是否可以使用不同类型的 Status 元素.

In this latest case, you can try to implement another xsd with xs:choice instead of xs:sequence. But I am not sure you can use Status elements with different types.

为了快速验证,您可以试用免费的在线 XML - XSD 验证器,因为您的案例很小,您可以轻松完成.

For quick validation, you can try a free online XML - XSD Validator, as your case is small you can easily do that.

另外,注意序列定义:

  • XSD 中的价格不能为空
  • Detail simpleType 与您的示例不匹配 (https://...)
  • 您的 XSD 中没有详细的响应类型

这篇关于使用 XSD 反序列化字符串时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆