【发布时间】:2020-08-07 10:50:15
【问题描述】:
我有一堆需要反序列化并存储在数据库中的 xml 文件。 我发现了一个出色的 XML 反序列化器的通用实现。唯一不方便的是我无法反序列化摄氏度符号。
以下 XML 示例包含摄氏度符号,我无法对其进行反序列化:
<pt>
<ch>1</ch>
<type>Analog</type>
<chtype>Temperature</chtype>
<chunits>°C</chunits>
<time>2020-05-03 22:10:00</time>
<value>0</value>
</pt>
或
<pt>
<ch>5</ch>
<type>Analog</type>
<chtype>Wind Direction</chtype>
<chunits>°</chunits>
<time>2020-05-03 22:10:00</time>
<value>0</value>
</pt>
我的反序列化器实现如下:
public class XmlConvert
{
public static string SerializeObject<T>(T dataObject)
{
if (dataObject == null)
{
return string.Empty;
}
try
{
using (StringWriter stringWriter = new System.IO.StringWriter())
{
var serializer = new XmlSerializer(typeof(T));
serializer.Serialize(stringWriter, dataObject);
return stringWriter.ToString();
}
}
catch (Exception ex)
{
return string.Empty;
}
}
public static T DeserializeObject<T>(string xml)
where T : new()
{
if (string.IsNullOrEmpty(xml))
{
return new T();
}
try
{
using (var stringReader = new StringReader(xml))
{
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(stringReader);
}
}
catch (Exception ex)
{
return new T();
}
}
}
我用来转换的类如下:
/// <summary>
/// Container for a single data point.
/// </summary>
public class MessageDataPoint
{
/// <summary>
/// Channel number for data point.
/// </summary>
[System.Xml.Serialization.XmlElement("ch")]
public string Ch { get; set; }
/// <summary>
/// Point type (Analog, Flow)
/// </summary>
[System.Xml.Serialization.XmlElement("type")]
public string Type { get; set; }
/// <summary>
///
/// </summary>
[System.Xml.Serialization.XmlElement("chtype")]
public string ChType { get; set; }
/// <summary>
/// Channel units
/// </summary>
[System.Xml.Serialization.XmlElement("chunits")]
public string ChUnits { get; set; }
/// <summary>
/// Point timestamp.
/// </summary>
[System.Xml.Serialization.XmlElement("time")]
public string Time { get; set; }
[System.Xml.Serialization.XmlIgnore]
public DateTime? TimeParsed
{
get
{
DateTime.TryParse(Time, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dt);
return dt;
}
private set { }
}
/// <summary>
/// Channel Value
/// </summary>
[System.Xml.Serialization.XmlElement("value")]
public string Value { get; set; }
}
反序列化器实现如下:
public async Task<string> GetFileAsStream(string key)
{
var content = string.Empty;
try
{
GetObjectRequest request = new GetObjectRequest
{
BucketName = bucketName,
Key = key
};
using (GetObjectResponse response = await client.GetObjectAsync(request))
{
using (StreamReader reader = new StreamReader(response.ResponseStream))
{
content = await reader.ReadToEndAsync();
var logger = XmlConvert.DeserializeObject<Logger>(content);
// code removed for brevity
}
}
}
}
结果如下:
<pt>
<ch>1</ch>
<type>Analog</type>
<chtype>Temperature</chtype>
<chunits>�C</chunits>
<time>2020-05-03 22:10:00</time>
<value>0</value>
</pt>
<pt>
<ch>2</ch>
<type>Analog</type>
<chtype>Wind Chill</chtype>
<chunits>�C</chunits>
<time>2020-05-03 22:10:00</time>
<value>0</value>
</pt>
有什么想法吗?
这是一个示例文件:
<?xml version="1.0" encoding="ISO-8859-15"?>
<logger>
<id>111111</id>
<mobileNumber>12345676</mobileNumber>
<serialNumber>01404</serialNumber>
<siteName>abcdef</siteName>
<siteId>abcdef</siteId>
<maintenanceflag>False</maintenanceflag>
<messages>
<message>
<id>123456789</id>
<number>123456</number>
<dateReceived>2020-05-04 00:02:25.0</dateReceived>
<dateCredited>2020-05-04 00:02:25.0</dateCredited>
<message> <siteId>abcdef</siteId>
<type>data</type>
<RST>2020-01-18 08:50:00</RST>
<RTC>2020-05-03 23:02:24</RTC>
<DST>2020-05-03 22:00:00</DST>
<mode>0</mode>
<SR>600</SR>
<pt>
<ch>1</ch>
<type>Analog</type>
<chtype>Temperature</chtype>
<chunits>°C</chunits>
<time>2020-05-03 23:00:00</time>
<value>0</value>
</pt>
<pt>
<ch>5</ch>
<type>Analog</type>
<chtype>Wind Direction</chtype>
<chunits>°</chunits>
<time>2020-05-03 23:00:00</time>
<value>0</value>
</pt>
</message>
<format>BINARY</format>
<source>FTP</source>
<batteryCondition>123</batteryCondition>
<signalStrength>12</signalStrength>
</message>
</messages>
</logger>
【问题讨论】:
-
您遇到的错误是什么?
-
您是否拥有正确的字符集和 XML 文档类型以使“°”符号成为有效字符?
-
嗨,亚历山大。感谢您调查它。我没有收到任何错误。我在 xml 上有这个编码
-
StreamReader不做编码检测,其编码默认为UTF-8。您最好的选择可能是将文件作为 ascii 读取,从"<?xml"部分直到第一次遇到'>',从中取出encoding=位,然后使用它来解析带有StreamReader的整个文件。 -
实际上,由于您是从 Stream 开始的...首先将整个内容作为字节接收。这将使对内容进行任何类型的检测变得更加容易。
标签: c# xml deserialization special-characters