热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于c#:XML反序列化非基于集合的响应

XML Deserialization For Non-Collection Based Responses我正在使用 API 来获取有关 Web 应用程序的一


XML Deserialization For Non-Collection Based Responses


我正在使用 API 来获取有关 Web 应用程序的一些信息。我编写了类来反序列化 XML 响应并添加了 XMLRoot、XMLElement 属性。对于带有子项集合的 XML 响应,我可以使用属性进行反序列化。例如










1
2
3
4
5
6
7
8
9



xml version="1.0" encoding="UTF-8"?>
<time-entries>

   <time-entry>

        //Other sub nodes

   time-entry>

   <time-entry>

        //Other sub nodes

   time-entry>
time-entries>


对于像上面这样的 XML 响应,我编写了一个 TimeEntry 类,该类具有时间入口节点的其他属性的属性。然后我用 TimeEntry 类的集合编写了另一个类,如下所示










1
2
3
4
5
6
7
8
9
10
11
12



[XmlRoot("time-entries")]
public class TimeEntryResponse
{

    public TimeEntryResponse()

    {

    }

    [XmlElement("time-entry")]

    public List<TimeEntry> TimeEntries { get; set; }

}



因此,使用 TimeEntryResponse 类,我可以反序列化 XML 响应,例如问题的顶部。

但我不能像下面的响应那样反序列化。










1
2
3
4
5
6



xml version="1.0" encoding="UTF-8"?>
<time-totals>

   <total-mins-sum type="integer">382743total-mins-sum>

   <non-billed-mins-sum type="integer">328988non-billed-mins-sum>

   <non-billable-hours-sum type="integer">3137.30non-billable-hours-sum>
time-totals>


我还为这个响应写了一个 TimeTotal 类。










1
2
3
4
5
6
7
8
9
10



[XmlRoot("time-totals")]
public class TimeTotal
{

    [XmlElement("total-mins-sum")]

    public double TotalMinsSum { get; set; }

    [XmlElement("non-billed-mins-sum")]

    public double NonBilledMinsSum { get; set; }

    [XmlElement("non-billable-hours-sum")]

    public double NonBillableHoursSum { get; set; }
}


然后我写了一个响应类。










1
2
3
4
5
6
7
8
9



public class TimeTotalsResponse : IEntityResponse
{

    public TimeTotalsResponse()

    {

    }

    public TimeTotal TimeTotal { get; set; }
}



如您所见,没有此响应的集合,而且我不知道应该添加响应类 TimeTotal 的哪些属性。

也许我可以直接将 TimeTotal 类的属性放入 TimeTotalResponse 类。但我将使用这个类来反序列化包含时间总计节点的类。



相关讨论




  • 为什么不直接反序列化到 TimeTotal 类?它应该可以工作。或者,如果您还需要实现 IEntityResponse 有 TimeTotalsResponse 子类 TimeTotal 而不是封装它。


  • @dbc 我不想序列化 TimeTotal 类。我需要返回一个从 IEntityResponse 派生的类,因为我在这个接口上使用泛型方法做了很多工作。如果您在评论中有不同的意思,您能用代码告诉它吗?






我不认为您可以使用开箱即用的 XmlSerialization 来做到这一点,因为您的对象不会直接映射到 XML。我能想到两种方法。

方法一:

由于 XML 可以直接反序列化为 TimeTotal,因此首先使用简单的静态方法序列化为 TimeTotal,并将其设置为新创建的 TimeTotalsResponse 的属性,例如:










1
2
3
4
5
6
7
8
9
10
11
12
13



static void Main(string[] args)
{

     var response = GetResponse(File.ReadAllText("XMLFile1.xml"));
}

static TimeTotalsResponse GetResponse(string xml)
{

    using (StringReader reader = new StringReader(xml))

    {

        var ser = new XmlSerializer(typeof(TimeTotal));

        return new TimeTotalsResponse() { TimeTotal = (TimeTotal)ser.Deserialize(reader) };

    }
}



方法二:

通过编写自己的 XmlSerializer 来自定义序列化,例如:










1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24



public class TimeTotalsResponseSerializer : IXmlSerializable
{

    public TimeTotalsResponse Response { get; set; }

    public void ReadXml(XmlReader reader)

    {

        Response = new TimeTotalsResponse();

        Response.TimeTotal = new TimeTotal();

        reader.ReadToDescendant("total-mins-sum");

        Response.TimeTotal.TotalMinsSum = reader.ReadElementContentAsDouble();

        Response.TimeTotal.NonBilledMinsSum = reader.ReadElementContentAsDouble();

        Response.TimeTotal.NonBillableHoursSum = reader.ReadElementContentAsDouble();

    }

    public XmlSchema GetSchema()

    {

        return null;

    }

    public void WriteXml(XmlWriter writer)

    {

    }
}



用法是;










1
2
3
4
5
6
7
8
9
10
11
12
13
14
15



static void Main(string[] args)
{

    XmlReaderSettings settings = new XmlReaderSettings()

    {

        IgnoreWhitespace = true

    };

    string xml = File.ReadAllText("XMLFile1.xml");

    using (XmlReader reader = XmlReader.Create(new StringReader(xml), settings))

    {

        var ser = new TimeTotalsResponseSerializer();

        ser.ReadXml(reader);

        var response = ser.Response;

    }
}





查看问题的最佳方法是对数据进行序列化。请参阅下面的代码。查看为 xsi:type="TimeEntries" 和 xsi:type="TimeTotalsResponse"

生成的两个 XML 文件










1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication1
{

    class Program

    {

        const string FILENAME1 = @"c:\temp\test1.xml";

        const string FILENAME2 = @"c:\temp\test2.xml";

        static void Main(string[] args)

        {

            TimeEntries timeEntries = new TimeEntries()

            {

                timeEntry = new List<TimeEntry>() {

                    new TimeEntry() {},

                    new TimeEntry() {},

                    new TimeEntry() {}

                }

            };

            TimeTotalsResponse timeTotals = new TimeTotalsResponse()

            {

                TotalMinsSum = new TypeInteger() { _type ="integer", _value = 382743 },

                NonBilledMinsSum = new TypeInteger() { _type ="integer", _value = 328988 },

                NonBillableHoursSum = new TypeInteger() { _type ="integer", _value = 3137.30 }

            };

            XmlSerializer serializer = new XmlSerializer(typeof(TimeEntryResponse));

            StreamWriter writer = new StreamWriter(FILENAME1);

            serializer.Serialize(writer, timeEntries);

            writer.Flush();

            writer.Close();

            writer.Dispose();

            writer = new StreamWriter(FILENAME2);

            serializer.Serialize(writer, timeTotals);

            writer.Flush();

            writer.Close();

            writer.Dispose();

        }

    }

    [XmlInclude(typeof(TimeEntries))]

    [XmlInclude(typeof(TimeTotalsResponse))]

    [Serializable]

    public class TimeEntryResponse

    {

    }

    [XmlRoot("time-entries")]

    public class TimeEntries : TimeEntryResponse

    {

        [XmlElement("time-entry")]

        public List<TimeEntry> timeEntry { get; set; }

    }

    [XmlRoot("time-entry")]

    public class TimeEntry

    {

    }

    [XmlRoot("time-totals")]

    public class TimeTotalsResponse : TimeEntryResponse

    {

        [XmlElement("total-mins-sum")]

        public TypeInteger  TotalMinsSum { get; set; }

        [XmlElement("non-billed-mins-sum")]

        public TypeInteger NonBilledMinsSum { get; set; }

        [XmlElement("non-billable-hours-sum")]

        public TypeInteger NonBillableHoursSum { get; set; }

    }

    public class TypeInteger

    {

        [XmlAttribute("type")]

        public string _type { get; set; }

        [XmlText]

        public double _value { get; set; }

    }
}

a€?









推荐阅读
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
author-avatar
小菜鸟
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有