使用多态和异常处理进行XML反序列化

5
我正在使用Microsoft ASP.NET Web API创建一个服务,具有以下要求:
  1. 输入必须为XML(不是JSON)
  2. XML将遵循一种标准(无法向输入XML添加自定义元素名称/属性)
  3. 在反序列化时遇到异常(即数据值格式错误)时,必须将其记录为警告,并继续解析输入XML
  4. XML将包含元素集合,其中元素需要反序列化为从基类型派生的类型
要求1和2仅定义了我的输入。 我开始使用内置的System.Xml.Serialization.XmlSerializer类开发我的解决方案,但不得不放弃它,因为它无法处理第3个要求。
或者,我发现 YAXLib 提供了一种非常 有用的方法 来处理第3个要求。

YAXLib同样处理需求#4,但是只能通过在XML中利用自定义属性来实现:

  <ListOfObjects>
    <Object yaxlib:realtype="System.Int32">7</Object>
    <Object yaxlib:realtype="System.Double">3.14</Object>
    <Object yaxlib:realtype="System.String">Congrats</Object>
    <Object yaxlib:realtype="System.StringSplitOptions">RemoveEmptyEntries</Object>
  </ListOfObjects>

因为第二个要求的限制,我不能使用这种方法。我需要像 System.Xml.Serialization.XmlElementAttribute 这样的东西,这样我就可以在代码中指示序列化器,而不是在数据中指示它。是否存在现有的解决方案可以处理所有这些要求?

示例:

输入

<DEALS>
    <DEAL>
        <COLLATERALS>
            <COLLATERAL>xyz</COLLATERAL>
            <COLLATERAL>1.2</COLLATERAL>
            <COLLATERAL>4.5</COLLATERAL>
        </COLLATERALS>
        <LOANS>
            <LOAN>
                <CLOSING_INFORMATION />
            </LOAN>
        </LOANS>
    </DEAL>
</DEALS>

C# 类

public class DEAL
{
    [System.Xml.Serialization.XmlElementAttribute("COLLATERALS", typeof(COLLATERALS))]
    [System.Xml.Serialization.XmlElementAttribute("LOANS", typeof(LOANS))]
    [YAXCollection(YAXCollectionSerializationTypes.RecursiveWithNoContainingElement)]
    public object[] Items
    {
        get
        {
            return this.itemsField;
        }
        set
        {
            this.itemsField = value;
        }
    }

    // Remaining implementation details omitted..
}

public class COLLATERALS { /* details omitted.. */ }
public class LOANS { /* details omitted.. */ }

public class COLLATERAL
{
    [System.Xml.Serialization.XmlTextAttribute()]
    public decimal Value { get; set; }
}

期望输出

DEALS类中的Items集合中的对象应反序列化为它们各自的类型:COLLATERALSLOANS。此外,值为“xyz”的第一个抵押品不会被反序列化(因为类型是decimal),但其余有效的COLLATERAL项将被反序列化。应该以某种方式记录将'xyz'解析为十进制数时出现的错误。


3
我建议编写一个XML架构,定义有效/无效的输入。 (XML已经有定义架构的语法。)这将简化测试过程,使得您和潜在用户都可以在不实际访问服务本身的情况下验证输入是否有效。 - Servy
@Servy 这是最初的想法。我有一个定义有效模式的XSD。然而,我们有一些用户将向我们发送来自其现有软件的数据,并且不能保证他们能够在发送数据之前对XSD进行验证,因此我们将验证移动到解析时刻。 - Michael Hornfeck
显然,您需要一个过于宽容的解析器,这样您就不能只是插入XSD并完成,但是定义它仍然是值得的,因为它将有助于您的开发工作、测试工作,并帮助编写使用此服务的代码的开发人员(假设您发布XSD)。由于它实际上并没有解决我发布的问题,所以我发表了评论而不是答案。 - Servy
@Servy 感谢您的建议。我认为,由于我的问题是关于处理这4个要求的解决方案,您提出的客户端验证XML与XSD相结合,在服务器上使用XmlSerializer进行多态反序列化的解决方案将是最佳选择。您可以将其发布为答案,我会接受。 - Michael Hornfeck
1个回答

0

您可以使用 XML Schema(XSD 文件)来定义 XML 文件的有效格式。现有工具可验证特定文件是否符合模式。

通过公开提供此模式,您将能够允许客户验证其自己的请求,而无需实际与您的 Web 服务进行交互。这将使他们能够查看其输入是否有效,以及如果他们需要对哪些内容进行复杂分析才能符合要求,他们将能够自行完成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接