简体   繁体   English

使用SWXMLHash反序列化xml时处理缺少的属性

[英]Handling missing properties when deserializing xml using SWXMLHash

I've been following the examples at SWXMLHash to deserialize an XML file. 我一直在遵循SWXMLHash上的示例反序列化XML文件。 It is working quite well, but I am not sure how to handle cases when the XML input is incomplete: 它工作得很好,但是我不确定在XML输入不完整的情况下如何处理情况:

For example, suppose the XML input is this: 例如,假设XML输入是这样的:

<shippingInfo>
            <shippingServiceCost currencyId="USD">0.0</shippingServiceCost>
            <shippingType>Free</shippingType>
            <shipToLocations>US</shipToLocations>
            <expeditedShipping>true</expeditedShipping>
            <oneDayShippingAvailable>false</oneDayShippingAvailable>
            <handlingTime>1</handlingTime>
</shippingInfo>

To deserialize this XML, I create the following struct that is an XMLIndexerDeserializable 为了反序列化此XML,我创建了以下结构,该结构是XMLIndexerDeserializable

import SWXMLHash

struct ShippingInfo: XMLIndexerDeserializable
{
    let currencyId: String
    let shippingServiceCost: Double
    let shippingType: String
    let shipToLocations: String
    let expeditedShipping: Bool
    let oneDayShippingAvailable: Bool
    let handlingTime: Int

    static func deserialize(_ node: XMLIndexer) throws -> ShippingInfo 
    {
        return try ShippingInfo(
            currencyId: node["shippingServiceCost"].value(ofAttribute: "currencyId"),
            shippingServiceCost: node["shippingServiceCost"].value(),
            shippingType: node["shippingType"].value(),
            shipToLocations: node["shipToLocations"].value(),
            expeditedShipping: node["expeditedShipping"].value(),
            oneDayShippingAvailable: node["oneDayShippingAvailable"].value(),
            handlingTime: node["handlingTime"].value()
        )
    }
}

The code above works, until the shippingInfo XML misses an element, like so: 上面的代码可以正常工作,直到shippingInfo XML缺少一个元素为止,如下所示:

<shippingInfo>
            <shippingServiceCost currencyId="USD">0.0</shippingServiceCost>
            <shippingType>Free</shippingType>
            <shipToLocations>Worldwide</shipToLocations>
            <expeditedShipping>false</expeditedShipping>
            <oneDayShippingAvailable>false</oneDayShippingAvailable>
</shippingInfo>

The 2nd XML above is missing the property "handlingTime" . 上面的第二个XML缺少属性“ handlingTime” Running the deserialization code above would throw an exception at node["handlingTime"].value() 运行上面的反序列化代码将在node [“ handlingTime”]。value()处引发异常

One approach to fix this problem is to try to catch the exception whenever we access the XMLIndexer's key, and pass in a default value to the property if the exception is thrown which means the key isn't there. 解决此问题的一种方法是,每当我们访问XMLIndexer的键时尝试捕获异常,如果抛出异常(表示该键不存在),则将默认值传递给属性。 I don't think this is best approach though. 我认为这不是最好的方法。

What is the best approach to deserialize XML when the XML is missing properties? 当XML缺少属性时,反序列化XML的最佳方法是什么?

Change the declaration of your handlingTime property from Int to Int? 将您的handlingTime属性的声明从Int更改为Int? , like so: ,就像这样:

let handlingTime: Int?

It needs to be nullable so that the deserialization can support a value that doesn't exist. 它必须可以为空,以便反序列化可以支持不存在的值。

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM