从一个 XML 文件反序列化两个单独的对象 [英] Deserialize two separate objects from one XML file

查看:29
本文介绍了从一个 XML 文件反序列化两个单独的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将两个对象序列化为 XML 并写入两个单独的 XML 文件,然后将两个文件合并为一个文件.我想要做的是能够从合并的文件中单独反序列化每个对象.

I am serializing two objects to XML and writing to two separate XML files, then merging the two files to one file. What I want to do is be able to deserialize each object separately from the merged file.

<?xml version="1.0" encoding="utf-8"?>
<root>
  <ArrayOfMapItem>
    <MapItem>
      <EpgId xmlns="Company.Domain.Name.Space">0000DAC2-0000-0000-0000-000000000000</EpgId>
      <MapId xmlns="Company.Domain.Name.Space">5D195A5B-FBBF-4042-8AB3-E4558CA1D347</MapId>
      <ServiceCollectionId xmlns="Company.Domain.Name.Space">657A62F8-260A-482B-BC86-7D6DEA9D8984</ServiceCollectionId>
      <ServiceCollectionName xmlns="Company.Domain.Name.Space">Rich_Gold</ServiceCollectionName>
      <Services xmlns="Company.Domain.Name.Space">Rich_Gold</Services>
      <TunerPosition xmlns="Company.Domain.Name.Space">1</TunerPosition>
    </MapItem>
    <MapItem>
      <EpgId xmlns="Company.Domain.Name.Space">000010FA-0000-0000-0000-000000000000</EpgId>
      <MapId xmlns="Company.Domain.Name.Space">5DF26284-D0EA-4071-9DA0-22E463314D65</MapId>
      <ServiceCollectionId xmlns="Company.Domain.Name.Space">83CFD40E-C7FB-420D-B9FC-5E5B711B9E74</ServiceCollectionId>
      <ServiceCollectionName xmlns="Company.Domain.Name.Space">G-D9154-DF8-01_SC</ServiceCollectionName>
      <Services xmlns="Company.Domain.Name.Space">G-D9154-DF8-PIP-01, G-D9154-DF8-FS-01</Services>
      <TunerPosition xmlns="Company.Domain.Name.Space">2</TunerPosition>
    </MapItem>
  <ArrayOfMapItem>
  <ArrayOfArrayOfGrant>
    <ArrayOfGrant>
      <Grant ResourceId="5df26284-d0ea-4071-9da0-22e463314d65" PrincipalExternalId="roman" PrincipalType="Group" ResType="Package" Right="Record">
        <Conditions xmlns="http://www.company.com/egtv/bss">
          <TimeExpiration Start="2014-05-01T07:00:00" End="9999-12-31T23:59:59.997" Type="TimeExpiration" Expiration="9999-12-31T23:59:59" />
        </Conditions>
      </Grant>
      <Grant ResourceId="5df26284-d0ea-4071-9da0-22e463314d65" PrincipalExternalId="PETSIN" PrincipalType="Group" ResType="Package" Right="Record">
        <Conditions xmlns="http://www.company.com/egtv/bss">
          <TimeExpiration Start="2014-04-04T18:52:24.867" End="9999-12-31T23:59:59.997" Type="TimeExpiration" Expiration="9999-12-31T23:59:59" />
        </Conditions>
      </Grant>
      <Grant ResourceId="5df26284-d0ea-4071-9da0-22e463314d65" PrincipalExternalId="PETSIN" PrincipalType="Group" ResType="Package" Right="Record">
        <Conditions xmlns="http://www.company.com/egtv/bss">
          <TimeExpiration Start="2014-04-04T18:53:28.797" End="9999-12-31T23:59:59.997" Type="TimeExpiration" Expiration="9999-12-31T23:59:59" />
        </Conditions>
      </Grant>
      <Grant ResourceId="5df26284-d0ea-4071-9da0-22e463314d65" PrincipalExternalId="PETSIN" PrincipalType="Group" ResType="Package" Right="Record">
        <Conditions xmlns="http://www.company.com/egtv/bss">
          <TimeExpiration Start="2014-04-04T19:17:42.983" End="9999-12-31T23:59:59.997" Type="TimeExpiration" Expiration="9999-12-31T23:59:59" />
        </Conditions>
      </Grant>
    </ArrayOfGrant>
    <ArrayOfGrant>
      <Grant ResourceId="6f26ecfd-4bfe-4c5d-af0b-164a93f448e8" PrincipalExternalId="roman" PrincipalType="Group" ResType="Package" Right="Record">
        <Conditions xmlns="http://www.company.com/egtv/bss">
          <TimeExpiration Start="2014-05-01T07:00:00" End="9999-12-31T23:59:59.997" Type="TimeExpiration" Expiration="9999-12-31T23:59:59" />
        </Conditions>
      </Grant>
    </ArrayOfGrant>
  </ArrayOfArrayOfGrant>
</root>

我已经试过了:

    XmlSerializer mySerializer = new XmlSerializer(typeof(MapItem[]), new XmlRootAttribute("ArrayOfMapItem"));
    using (FileStream fs = new FileStream("DataMerged.xml", FileMode.Open))
    {
        MapItem[] r;
        r = (MapItem[]) mySerializer.Deserialize(fs);
    .....
    }

但是当代码到达mySerializer.Deserialize"时,它会得到:

But when the code gets to "mySerializer.Deserialize" it get:

InnerException: System.InvalidOperationException
       HResult=-2146233079
       Message=<root xmlns=''> was not expected.
       Source=Microsoft.GeneratedCode
       StackTrace:
            at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderChannelMapItemArray.Read3_ArrayOfChannelMapItem()

有没有一种方法可以从一个合并的文件中单独反序列化对象?当我反序列化对象时,它们仍然在单独的文件中,我没有问题.

Is there a way I can deserialize the objects individually from one merged file? When I deserialize the objects while they are still in separate files I have no problems.

感谢任何人可以提供的任何帮助

Thanks for any help anyone can provide

推荐答案

一种简单的方法是将 XML 加载到 XDocument,选择每个部分,并使用您的现有的序列化代码.

An easy way to do this is to load the XML into an XDocument, pick out each section, and deserialize each one individually using your existing serialization code.

首先介绍一些扩展方法:

First, some extension methods:

public static class XObjectExtensions
{
    public static T Deserialize<T>(this XElement element)
    {
        return element.Deserialize<T>(new XmlSerializer(typeof(T)));
    }

    public static T Deserialize<T>(this XElement element, XmlSerializer serial)
    {
        using (var reader = element.CreateReader())
        {
            object result = serial.Deserialize(reader);
            if (result is T)
                return (T)result;
        }
        return default(T);
    }
}

然后,做:

        var xml = GetXml(); // Load the XML.  (In my test code it's just a string literal.)
        var doc = XDocument.Parse(xml); // In your case, you would use XDocument.Load(filename)

        var mapXml = doc.Root.Element("ArrayOfMapItem");
        var grantXml = doc.Root.Element("ArrayOfArrayOfGrant");

        if (mapXml != null)
        {
            var mapItems = mapXml.Deserialize<MapItem[]>();
            Debug.WriteLine(mapItems.GetXml()); // Two items deserialized successfully.
        }

        if (grantXml != null)
        {
            var grantItems = grantXml.Deserialize<Grant[][]>();
            Debug.WriteLine(grantItems.GetXml()); // Two arrays of arrays deserialized successfully.
        }

出于测试目的,我使用了您的类的以下缩写版本:

For testing purposes, I used the following abbreviated versions of your classes:

[XmlType("MapItem", Namespace="")]
public class MapItem
{
    [XmlElement(Namespace="Company.Domain.Name.Space")]
    public string EpgId { get; set; }
}

[XmlType("Grant", Namespace="")]
public class Grant
{
    [XmlAttribute("ResourceId")]
    public string ResourceId { get; set; }

    [XmlAttribute("PrincipalExternalId")]
    public string PrincipalExternalId { get; set; }
}

这篇关于从一个 XML 文件反序列化两个单独的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆