我使用API来获取有关Web应用程序的一些信息。我编写了用于反序列化XML响应的类,并添加了XMLRoot,XMLElement属性。对于具有子项集合的XML响应,我可以使用属性进行反序列化。例如
<?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类,其中包含time-entry节点的其他属性。然后我写了另一个带有TimeEntry类集合的类,如下所示
[XmlRoot("time-entries")]
public class TimeEntryResponse
{
public TimeEntryResponse()
{
}
[XmlElement("time-entry")]
public List<TimeEntry> TimeEntries { get; set; }
}
因此,使用TimeEntryResponse类,我可以像处理问题一样反序列化XML响应。
但我不能像下面的回复一样反序列化。
<?xml version="1.0" encoding="UTF-8"?>
<time-totals>
<total-mins-sum type="integer">382743</total-mins-sum>
<non-billed-mins-sum type="integer">328988</non-billed-mins-sum>
<non-billable-hours-sum type="integer">3137.30</non-billable-hours-sum>
</time-totals>
我还为此响应写了一个TimeTotal类。
[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; }
}
然后我写了一个回复课。
public class TimeTotalsResponse : IEntityResponse
{
public TimeTotalsResponse()
{
}
public TimeTotal TimeTotal { get; set; }
}
正如您所看到的,没有此回复的集合,我也不知道应该添加我的响应类TimeTotal的属性。
也许我可以直接将TimeTotal类的属性放在TimeTotalResponse类中。但我将使用此类进行另一个包含时间总计节点的类的反序列化。
答案 0 :(得分:0)
查看问题的最佳方法是序列化数据。见下面的代码。查看为xsi生成的两个XML文件:type =“TimeEntries”和xsi:type =“TimeTotalsResponse”
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; }
}
}
答案 1 :(得分:0)
我不认为您可以使用开箱即用的XmlSerialization来实现它,因为您的对象不会直接映射到XML。我可以想到两种方法。
方法1:
由于XML可以直接反序列化为TimeTotal,因此首先使用简单的静态方法序列化为TimeTotal,并将其设置为新创建的TimeTotalsResponse的属性,例如:
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) };
}
}
方法2: 通过编写自己的XmlSerializer来自定义序列化,例如:
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)
{
}
}
,用法是;
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;
}
}