Xml 使用 RestSharp 进行序列反序列化
Xml Sequence deserialization with RestSharp
我有来自 API 的 xml 供稿和 XML 序列。
<?xml version="1.0" encoding="UTF-8" ?>
<Function>
<Cmd>2002</Cmd>
<Status>1</Status>
<Cmd>2003</Cmd>
<Status>0</Status>
<Cmd>2004</Cmd>
<Status>0</Status>
<Cmd>1012</Cmd>
<Status>3</Status>
<Cmd>2006</Cmd>
<Status>0</Status>
<Cmd>2007</Cmd>
<Status>0</Status>
...
</Function>
我已经尝试了一些使用 Restsharp 进行反序列化的选项。理想情况下我想要类似下面的东西,但它显然不起作用。
public class MyResponse
{
public List<Setting> Settings { get; set;}
}
public class Setting
{
public int Cmd { get; set; }
public int Status { get; set; }
}
谢谢
您的 XML 与您的对象模型不匹配。
有两种简单的修复方法
* 让你的 XML 响应实际上包含一个列表结构
* 编写自定义解析器。
** https://github.com/restsharp/RestSharp/wiki/Deserialization
谁负责生成 XML/Soap?看起来像是手工制作的东西。
查看 Restsharp 页面上有关列表反序列化的示例:
<?xml version="1.0" encoding="utf-8" ?>
<NestedListSample>
<images>
<image src="1.gif">value1</image>
<image src="2.gif">value2</image>
<image src="3.gif">value3</image>
<image src="4.gif">value4</image>
</images>
</NestedListSample>
将映射到以下 C# 架构:
public class ListSample
{
public List<Image> Images { get; set; }
}
public class Image
{
public string Src { get; set; }
public string Value { get; set; }
}
您可以使用 DotNetXmlDeserializer
of RestSharp to make Microsoft's XmlSerializer
do the actual deserialization. Define your MyResponse
class as follows, using XML serialization attributes 指定元素名称以及对 Cmd/Status
交替元素序列的特殊处理:
[XmlRoot("Function")]
public class MyResponse
{
[XmlIgnore]
public List<Setting> Settings { get; set; }
/// <summary>
/// Proxy property to convert Settings to an alternating sequence of Cmd / Status elements.
/// </summary>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[XmlAnyElement]
public XElement[] Elements
{
get
{
if (Settings == null)
return null;
return Settings.SelectMany(s => new[] { new XElement("Cmd", s.Cmd), new XElement("Status", s.Status) }).ToArray();
}
set
{
if (value == null)
Settings = null;
else
Settings = value.Where(e => e.Name == "Cmd").Zip(value.Where(e => e.Name == "Status"), (cmd, status) => new Setting { Cmd = (int)cmd, Status = (int)status }).ToList();
}
}
}
然后反序列化如下:
var serializer = new DotNetXmlDeserializer();
var myResponse = serializer.Deserialize<MyResponse>(response);
原型fiddle.
我有来自 API 的 xml 供稿和 XML 序列。
<?xml version="1.0" encoding="UTF-8" ?>
<Function>
<Cmd>2002</Cmd>
<Status>1</Status>
<Cmd>2003</Cmd>
<Status>0</Status>
<Cmd>2004</Cmd>
<Status>0</Status>
<Cmd>1012</Cmd>
<Status>3</Status>
<Cmd>2006</Cmd>
<Status>0</Status>
<Cmd>2007</Cmd>
<Status>0</Status>
...
</Function>
我已经尝试了一些使用 Restsharp 进行反序列化的选项。理想情况下我想要类似下面的东西,但它显然不起作用。
public class MyResponse
{
public List<Setting> Settings { get; set;}
}
public class Setting
{
public int Cmd { get; set; }
public int Status { get; set; }
}
谢谢
您的 XML 与您的对象模型不匹配。 有两种简单的修复方法 * 让你的 XML 响应实际上包含一个列表结构 * 编写自定义解析器。 ** https://github.com/restsharp/RestSharp/wiki/Deserialization
谁负责生成 XML/Soap?看起来像是手工制作的东西。
查看 Restsharp 页面上有关列表反序列化的示例:
<?xml version="1.0" encoding="utf-8" ?>
<NestedListSample>
<images>
<image src="1.gif">value1</image>
<image src="2.gif">value2</image>
<image src="3.gif">value3</image>
<image src="4.gif">value4</image>
</images>
</NestedListSample>
将映射到以下 C# 架构:
public class ListSample
{
public List<Image> Images { get; set; }
}
public class Image
{
public string Src { get; set; }
public string Value { get; set; }
}
您可以使用 DotNetXmlDeserializer
of RestSharp to make Microsoft's XmlSerializer
do the actual deserialization. Define your MyResponse
class as follows, using XML serialization attributes 指定元素名称以及对 Cmd/Status
交替元素序列的特殊处理:
[XmlRoot("Function")]
public class MyResponse
{
[XmlIgnore]
public List<Setting> Settings { get; set; }
/// <summary>
/// Proxy property to convert Settings to an alternating sequence of Cmd / Status elements.
/// </summary>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
[XmlAnyElement]
public XElement[] Elements
{
get
{
if (Settings == null)
return null;
return Settings.SelectMany(s => new[] { new XElement("Cmd", s.Cmd), new XElement("Status", s.Status) }).ToArray();
}
set
{
if (value == null)
Settings = null;
else
Settings = value.Where(e => e.Name == "Cmd").Zip(value.Where(e => e.Name == "Status"), (cmd, status) => new Setting { Cmd = (int)cmd, Status = (int)status }).ToList();
}
}
}
然后反序列化如下:
var serializer = new DotNetXmlDeserializer();
var myResponse = serializer.Deserialize<MyResponse>(response);
原型fiddle.