将 XML classes 反序列化为一个 class 以写入数据库

Deserialize XML classes to one class for writing to database

我正在尝试反序列化 XML 并使用 entity framework 将结果保存到数据库中。

代码的第一部分只是从 API 中获取所需的 xml 文件。 请看下面:

    public static void Main()
    {
        Program semoAPI = new Program();

        using (WebClient webClient = new WebClient())
        {
            WebClient n = new WebClient();


            //Bid Ask Curves
            var bidAskCurves = n.DownloadString("https://reports.semopx.com/api/v1/documents/static-reports?" +
            "page=1&page_size=1&order_by=ASC&ReportName=Bid/Ask%20Curves&Group=Market%20Data");

            semoReports = JsonConvert.DeserializeObject<SemoReports>(bidAskCurves);

            Console.WriteLine("Bid Ask Curves Report: ");

            Console.WriteLine(semoReports.ResourceBaseUri + "/" + semoReports.Items[0].ResourceName);

            string bidAskCurvesXML = semoReports.ResourceBaseUri + "/" + semoReports.Items[0].ResourceName;

            XDocument bacDoc = XDocument.Load(bidAskCurvesXML);

            //Execute DeserializeBidAskCurves
            semoAPI.DeserializeBidAskCurves(bidAskCurvesXML);
        }
    }

下面是我的 class 的设置方式,其中包含我需要的 XML 元素:

namespace SEMO_app
{
    [XmlRoot("BidAskCurves")]
    public class BidAskCurves
    {
        [Key]
        public int ReportID { get; set; }

        [XmlElement("MarketArea")]
        public MarketArea[] MarketAreas{ get; set; }
    }

    public class MarketArea
    {
        public string MarketAreaName { get; set; }

        [XmlElement("DeliveryDay")]
        public DeliveryDay[] DeliveryDays { get; set; }
    }

    public class DeliveryDay
    {
        public string Day { get; set; }

        [XmlElement("TimeStep")]
        public TimeStep[] TimeSteps{ get; set; }
    }

    public class TimeStep
    {
        public string TimeStepID { get; set; }

        [XmlElement("Purchase")]
        public Purchase[] Purchases { get; set; }
    }

    public class Purchase
    {
        public string Price { get; set; }

        public string Volume { get; set; }
    }
} 

从这里我想反序列化 XML 并将信息保存到数据库,下面是我目前拥有的反序列化 XML 的代码,并在console.writesection.

但是我无法将这些值保存到数据库中 table。代码符合并执行得很好,并且数据库 table 更新,但是 table 只包含一个报告 ID 列。我希望它包含 console.write 部分中列出的项目。

        private void DeserializeBidAskCurves(string filename)
    {
        //Visual only not needed
        Console.WriteLine("\n" + "Reading BidAskCurves XML File");
        Console.WriteLine("===========================================================");

        // Create an instance of the XmlSerializer.
        XmlSerializer serializer = new XmlSerializer(typeof(BidAskCurves));

        // Declare an object variable of the type to be deserialized.
        BidAskCurves item;

        using (XmlReader reader = XmlReader.Create(filename))
        {
            // Call the Deserialize method to restore the object's state.
            item = (BidAskCurves)serializer.Deserialize(reader);

            //Write out the properties of the object. (Visual Only, not needed)
            Console.Write(
                item.MarketAreas[0].MarketAreaName + "\t" +
                item.MarketAreas[0].DeliveryDays[0].Day + "\t" +
                item.MarketAreas[0].DeliveryDays[0].TimeSteps[0].TimeStepID + "\t" +
                item.MarketAreas[0].DeliveryDays[0].TimeSteps[0].Purchases[0].Price + "\t" +
                item.MarketAreas[0].DeliveryDays[0].TimeSteps[0].Purchases[0].Volume);


            //write the properties to the db 
            using (SEMOContext context = new SEMOContext())
            {
                context.BidAskCurvesReports.Add(item);
                context.SaveChanges();
            }
        }
    }

Link 到 xml 文件: https://reports.semopx.com/documents/BidAskCurves_NI-IDA3_20190401_20190401161933.xml

提前感谢您的帮助。

最初,很难知道到底是什么问题?

但是在访问由

生成的 URI 之后
string bidAskCurvesXML = semoReports.ResourceBaseUri + "/" + semoReports.Items[0].ResourceName;

也就是https://reports.semopx.com/documents/BidAskCurves_NI-IDA3_20190401_20190401161933.xml

因此,您使用的 class 结构与 URI 生成的 xml 不同。

您需要为您的 xml

使用以下 class 结构
[XmlRoot("Purchase")]
public class Purchase
{
    [XmlElement("Price")]
    public string Price { get; set; }
    [XmlElement("Volume")]
    public string Volume { get; set; }
}

[XmlRoot("Sell")]
public class Sell
{
    [XmlElement("Price")]
    public string Price { get; set; }
    [XmlElement("Volume")]
    public string Volume { get; set; }
}

[XmlRoot("TimeStep")]
public class TimeStep
{
    [XmlElement("TimeStepID")]
    public string TimeStepID { get; set; }
    [XmlElement("Purchase")]
    public List<Purchase> Purchase { get; set; }
    [XmlElement("Sell")]
    public List<Sell> Sell { get; set; }
}

[XmlRoot("DeliveryDay")]
public class DeliveryDay
{
    [XmlElement("Day")]
    public string Day { get; set; }
    [XmlElement("TimeStep")]
    public List<TimeStep> TimeStep { get; set; }
}

[XmlRoot("MarketArea")]
public class MarketArea
{
    [XmlElement("MarketAreaName")]
    public string MarketAreaName { get; set; }
    [XmlElement("DeliveryDay")]
    public DeliveryDay DeliveryDay { get; set; }
}

[XmlRoot("BidAskCurves")]
public class BidAskCurves
{
    [XmlElement("MarketArea")]
    public MarketArea MarketArea { get; set; }
}

并且在使用上面的 class 结构和 XmlSerializer 之后,总共有 12 个可用的时间戳

用法:

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

BidAskCurves item;

using (XmlReader reader = XmlReader.Create("https://reports.semopx.com/documents/BidAskCurves_NI-IDA3_20190401_20190401161933.xml"))
{
    item = (BidAskCurves)serializer.Deserialize(reader);

    //Your code to add above parsed data into database.
}

输出:(来自调试器)

编辑 1:

先加上买入的量价,再加上卖出的量价,

...

item = (BidAskCurves)serializer.Deserialize(reader);

foreach (var ts in item.MarketArea.DeliveryDay.TimeStep)
{
    BidAskCurvesData bidAskCurvesData = new BidAskCurvesData
    {
        ReportID = 123,
        MarketAreaName = item.MarketArea.MarketAreaName,
        Day = item.MarketArea.DeliveryDay.Day,
        TimeSetID = ts.TimeStepID,
        PurchasePrice = ts.Purchase[0].Price,
        PurchaseVolume = ts.Purchase[0].Volume,
        SellPrice = ts.Sell[0].Price,
        SellVolume = ts.Sell[0].Volume
    };

    using (SEMOContext context = new SEMOContext())
    {
        context.BidAskCurvesReports.Add(item);
        context.SaveChanges();
    }
}
    static void Main(string[] args)
    {
        using (WebClient webClient = new WebClient())
        {
            //Bid Ask Curves
            var bidAskCurves = webClient.DownloadString("https://reports.semopx.com/documents/BidAskCurves_NI-IDA3_20190401_20190401161933.xml");

            var serializer = new XmlSerializer(typeof(BidAskCurves));
            BidAskCurves result;

            using (TextReader reader = new StringReader(bidAskCurves))
            {
                // here it is
                result = (BidAskCurves)serializer.Deserialize(reader);
            }
        }

        Console.ReadKey();
    }

和xml个对象:

[XmlRoot(ElementName = "Purchase")]
public class Purchase
{
    [XmlElement(ElementName = "Price")]
    public string Price { get; set; }
    [XmlElement(ElementName = "Volume")]
    public string Volume { get; set; }
}

[XmlRoot(ElementName = "Sell")]
public class Sell
{
    [XmlElement(ElementName = "Price")]
    public string Price { get; set; }
    [XmlElement(ElementName = "Volume")]
    public string Volume { get; set; }
}

[XmlRoot(ElementName = "TimeStep")]
public class TimeStep
{
    [XmlElement(ElementName = "TimeStepID")]
    public string TimeStepID { get; set; }
    [XmlElement(ElementName = "Purchase")]
    public List<Purchase> Purchase { get; set; }
    [XmlElement(ElementName = "Sell")]
    public List<Sell> Sell { get; set; }
}

[XmlRoot(ElementName = "DeliveryDay")]
public class DeliveryDay
{
    [XmlElement(ElementName = "Day")]
    public string Day { get; set; }
    [XmlElement(ElementName = "TimeStep")]
    public List<TimeStep> TimeStep { get; set; }
}

[XmlRoot(ElementName = "MarketArea")]
public class MarketArea
{
    [XmlElement(ElementName = "MarketAreaName")]
    public string MarketAreaName { get; set; }
    [XmlElement(ElementName = "DeliveryDay")]
    public DeliveryDay DeliveryDays { get; set; }
}

[XmlRoot(ElementName = "BidAskCurves")]
public class BidAskCurves
{
    [XmlElement(ElementName = "MarketArea")]
    public MarketArea MarketAreas { get; set; }
}

编辑

循环结果:

foreach (var item in deliveryDays.TimeStep)
{
    // var day = deliveryDays.Day
    var timeStep_Purchase = item.Purchase;
    var timeStep_Sell = item.Sell;
    var timeStep_Id = item.TimeStepID;
}