不确定如何处理非固定的XML数据类型

本文关键字:XML 数据类型 何处理 处理 不确定 | 更新日期: 2023-09-27 18:06:54

我正在读取一个XML文件,并使用其中的数据创建一个新对象,然后使用LINQ设置对象属性和读取数据。

例如,XML的一个部分如下所示:

<heat_index_string>NA</heat_index_string>
<heat_index_f>NA</heat_index_f>
<heat_index_c>NA</heat_index_c>
<windchill_string>NA</windchill_string>
<windchill_f>NA</windchill_f>
<windchill_c>NA</windchill_c>
<pressure_mb>1013</pressure_mb>
<pressure_in>29.92</pressure_in>

正常情况下,这些"NA"将由double(例如:public double HeatIndexC { get; set; })表示,但是如果该数据无法从服务中获得,则服务返回"NA"。在XML中没有其他信息给出可用或不可用的数据列表。

我这样读XML:

    var data = from i in weather.Descendants("current_observation")
               select new CurrentConditions
               {
                   HeatIndexC = (double)i.Element("heat_index_c"),
                   //Set other properties here
               };

可以看到,只要服务返回double类型就可以正常工作,但是一旦它返回字符串,就会导致异常。

那么,我该怎么做呢?我的第一个想法是为每个部分创建更多的属性,像这样:

public bool TemperatureAvaliable { get; set; };

我的另一个想法是只使用字符串类型,但这似乎相当不灵活,而且根本不习惯。

需要说明的是:我不知道如何处理一个有时返回double,有时返回string的服务。此外,该服务没有说明何时返回字符串或双精度类型。

不确定如何处理非固定的XML数据类型

我将使用Nullable<double>(又名double?)。那么问题是:如何将"NA"转换为double? ?这里有一个方法:

var data = from i in weather.Descendants("current_observation")
           select new CurrentConditions
           {
               HeatIndexC = ToNullableDouble(i.Element("heat_index_c")),
               //Set other properties here
           };
double? ToNullableDouble(object xml)
{
    if (xml == null)
        return null;
    if (xml is double)
        return (double?)xml;
    double value;
    return double.TryParse(xml.ToString(), out value) ? value : (double?)null;
}

您可能还希望显式地查找"NA",然后在出现任何无法识别的字符串时抛出异常,而不是静默地删除意外的数据。

编辑我注意到XElement还定义了这个转换操作符,这可能是处理这个问题的更好方法:
var data = from i in weather.Descendants("current_observation")
       select new CurrentConditions
       {
           HeatIndexC = (double?)i.Element("heat_index_c"),
           //Set other properties here
       };

不强制转换为双精度类型,使用TryParse

如果heatIndex没有解析,我假设默认值为0。使用可空的双精度类型可能是更合适的选择。

double heatIndexC;
var data = from i in weather.Descendants("current_observation")  
    select new CurrentConditions
    {
    var HeatIndexC = double.TryParse(i.Element("heat_index_c")
                                      .Value, out heatIndexC) 
                                     ? heatIndexC : 0,
        //Set other properties here
    };

编辑:固定输出值

小提琴