在 C# 中使用属性反序列化 XML

2024-02-17

我在反序列化 API 调用的 XML 响应时遇到问题。我的“选项”对象的属性“描述”为空。

下面是 XML 的示例:

<vehicle found="1">
   <description>VehicleDescText</description>
   <buildDate>2000-11-20</buildDate>
   <modelYear>2001</modelYear>
   <optionList>
      <option code="UH8">OptionDesc1</option>
      <option code="UH8">OptionDesc2</option>
   </optionList>
</vehicle>

以下是 C# 类的示例:

[DataContract]
[XmlRoot("vehicle")]
public class Vehicle
{
    [DataMember]
    [XmlAttribute("found")]
    public bool Found { get; set; }

    [DataMember]
    [XmlElement("description")]
    public string Description { get; set; }

    [DataMember]
    [XmlElement("buildDate")]
    public string BuildDate { get; set; }

    [DataMember]
    [XmlElement("modelYear")]
    public string ModelYear { get; set; }

    [DataMember]
    [XmlElement("optionList")]
    public List<Option> OptionList { get; set; }
}

public class Option
{
    [DataMember]
    [XmlAttribute("code")]
    public string Code { get; set; }

    [DataMember]
    [XmlElement("option")]
    public string Description { get; set; }
}

反序列化对象如下所示:

var xmlDeserializer = new RestSharp.Deserializers.XmlDeserializer();
results = xmlDeserializer.Deserialize<Vehicle>(response);

我这里哪里出错了?由于我不想修改底层数据模型,我可以添加或修改哪些属性来解决问题?


您已标记您的类型XML 序列化器属性 https://learn.microsoft.com/en-us/dotnet/standard/serialization/attributes-that-control-xml-serialization and 数据契约属性 https://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx,但是您正在使用的解串器,RestSharp.Deserializers.XmlDeserializer https://github.com/restsharp/RestSharp/blob/master/RestSharp/Deserializers/XmlDeserializer.cs,不支持这些属性。

相反,正如其中所解释的文档 https://github.com/restsharp/RestSharp/wiki/Deserialization,它支持[DeserializeAs] https://github.com/restsharp/RestSharp/blob/master/RestSharp/Deserializers/DeserializeAsAttribute.cs允许控制 XML 节点名称和元素与属性状态的属性。

但正如中所指出的@apocalypse 的回答 https://stackoverflow.com/a/47024374/3744182这个较旧的问题 https://stackoverflow.com/q/12223369/3744182文档中有一个关于将元素值反序列化为属性值的特殊情况:

如果返回的XML是这样的:

<Response>Hello world</Response>

无法在 C# 类中直接表示它:

public class Response {
}

您需要一些东西来保存 Response 元素的值。在这个 在这种情况下,添加一个名为 Value 的属性,它将被填充:

public class Response {
     public string Value { get; set; }
}

在搜索匹配元素之间检查此条件 名称和匹配的属性名称。

IE。如果你重命名Description to Value您将能够成功反序列化该 XML。 (样本小提琴#1 https://dotnetfiddle.net/MMPn0d.)

但是,您似乎不想重命名您的Description财产。如果是这样,您可以改为申请[DeserializeAs(Name = "Value")]对其进行特殊情况将再次适用:

public class Option
{
    public string Code { get; set; }

    [DeserializeAs(Name = "Value")]
    public string Description { get; set; }
}

Sample 小提琴#2 https://dotnetfiddle.net/5mDPpg.

最后,作为替代解决方案,您可以切换到RestSharp.Deserializers.DotNetXmlDeserializer https://github.com/restsharp/RestSharp/blob/master/RestSharp/Deserializers/DotNetXmlDeserializer.cs并使用常规XmlSerializer属性,具体来说[XmlText] https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmltextattribute.aspx。因此你的代码将变成:

var xmlDeserializer = new RestSharp.Deserializers.DotNetXmlDeserializer();
var results = xmlDeserializer.Deserialize<Vehicle>(response);

你的类型看起来像:

[XmlRoot("vehicle")]
public class Vehicle
{
    [XmlAttribute("found")]
    public bool Found { get; set; }

    [XmlElement("description")]
    public string Description { get; set; }

    [XmlElement("buildDate")]
    public string BuildDate { get; set; }

    [XmlElement("modelYear")]
    public string ModelYear { get; set; }

    [XmlArray("optionList")]
    [XmlArrayItem("option")]
    public List<Option> OptionList { get; set; }
}

public class Option
{
    [XmlAttribute("code")]
    public string Code { get; set; }

    [XmlText]
    public string Description { get; set; }
}

Sample 小提琴#3 https://dotnetfiddle.net/WtqlkF.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C# 中使用属性反序列化 XML 的相关文章

  • 如何从更高级别启动用户级别的 Exe

    我希望一个进程始终在用户级别运行 当它由以管理员级别运行的安装程序 自定义 而不是 msi 启动时 或者当用户登录时 环顾四周 我不确定这是否可能 最简单的方法是有 2 个进程 一种是普通用户 它启动提升 管理进程 然后管理进程可以使用 I
  • 了解 VerQueryValue

    在 MSDN 上 我注意到 VerQueryValue 函数的以下内容 lplp缓冲区 输出 低电压空洞当此方法返回时 包含指向 pBlock 指向的缓冲区中所请求版本信息的指针的地址 当关联的 pBlock 内存被释放时 lplpBuff
  • Excel的解析路径

    其实我想问以下问题 对于位于 目录中定义的 PATH 怎么能 我找出这些目录中的哪个 找到了 因为我需要使用 Process Run 从 C 运行 Excel 并且只需指示 Excel 即可正常工作 Windows 似乎知道在哪里可以找到它
  • 枚举 EMF 时丢失文本

    我在列举发票 emf http www mediafire com kdjwvvo7odyvwa6并将其复制到另一个但文本丢失了 令人惊讶的是 当我将其输出到窗口时 它绘制得非常完美 int CALLBACK EnhMetaFileProc
  • 获取不带波形符的泛型类名称[重复]

    这个问题在这里已经有答案了 我正在尝试获取类型名称T使用这个 typeof T Name 班级名称是ConfigSettings 而不是返回ConfigSettings它正在返回ConfigSettings 1 有什么具体原因吗 我怎样才能
  • 如何获取 PropertyGrid 的单元格值 (c#)?

    如何在 C 中获取属性网格项和项的值 例如 Name Ali LastName Ahmadi Name 和 LastName 是 propertygrid 的 2 个属性 PropertyGrid只是对象的组件模型表示的视图 我会说 查看组
  • DataGridView小数不排序

    好吧 我有一个 DataGridView 它的数据绑定如下 dataGridViewChartOre AutoGenerateColumns false dataGridViewChartOre DataSource xml GetOreC
  • Apple IOS 上的 C# 应用程序 [已关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有基于 C Net 的应用程序 有什么方法可以在 Apple IOS 上运行这些应用程序吗 我没有资
  • gcc 删除内联汇编代码

    看起来 gcc 4 6 2 删除了它认为函数中未使用的代码 test c int main void goto exit handler asm volatile jmp 0x0 exit return 0 拆解main 0x0804840
  • 关于 FirstOrDefault 或 SingleOrDefault

    FirstOrDefault 或 SingleOrDefault 将返回什么类型的数据 假设我的查询返回 3 条记录 例如 empid ename salary 1 joy 1500 2 rob 4500 3 jen 6500 所以如果我们
  • C++中的虚方法表存放在哪里?

    我想知道类对象 不是实例 而是类 如何存储在内存中 class A public int a virtual void f virtual A class B public A public int b void f final overr
  • 如何使用 HttpClient 验证 Pardot API

    我花了大约一天的时间尝试对 Pardot API 进行身份验证 它不喜欢我尝试发布消息正文的方式 所以我想发布对我有用的解决方案 如果您有任何建议或替代方案 我想听听 ServicePointManager SecurityProtocol
  • OpenMP 和 C++:this 指针

    Is thisOpenMP 中始终共享指针 尽管编译器不会抱怨以下代码default none pragma omp parallel for default none shared n for SInt i 0 i lt n i f i
  • 为什么.net中的数组只实现IEnumerable而不实现IEnumerable

    我正在实现自己的 ArrayList 类 当我意识到这一点时 我感到很惊讶 public System Collections Generic IEnumerator
  • 比较 C# 中的对象属性[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案或互动
  • 如何重写(重新实现)QFileSystemModel 中的成员函数

    我已经为此苦苦挣扎了一段时间 Qt s QFileSystemModel由于图标获取算法非常糟糕 在获取数百个文件时速度非常慢 我想完全禁用图标 它们被提取到QFileSystemModel data方法不是虚拟的 QFileSystemM
  • Opencv 对象检测:ORB GPU 检测器和 SURF GPU 描述符提取器

    我只是做了一个小实验来尝试不同的检测器 描述符组合 我的代码使用 ORB GPU 检测器来检测特征 并使用 SURF GPU 描述符来计算描述符 我使用 BruteForceMatcher GPU 来匹配描述符 并使用 knnMatch 方
  • 错误:C# 尝试读取或写入受保护的内存

    我很难纠正这个错误 该应用程序在 4 台不同的机器上进行了测试 在其中 3 台上运行良好 但一台 Vista PC 在尝试通过 WebBrowser1 打开页面时出现此错误 解决这个问题的任何帮助对我都会非常有帮助 System Acces
  • Image.Save 异常“GDI+ 中发生一般错误。”保存到 MemoryStream 时

    我有一个服务器客户端应用程序 我想从服务器获取屏幕截图 但在线bitmap Save ms System Drawing Imaging ImageFormat Png 我得到这个例外 A generic error occurred in
  • 如何在 C# 中将 json 转换为平面结构

    我正在尝试用 C 编写函数 将 JSON 转换为键 值对 它应该支持数组 例如下面的 JSON title title value components component id id1 menu title menu title1 tit

随机推荐