簡體   English   中英

(De)使用一個類序列化不同的根元素名稱

[英](De)serializing different root element names using one class

我有幾個具有不同根元素的XML文件,但是相同類型的子元素,我希望能夠創建一個單獨的類來保存不同的根元素,而另一個類來保存每個子元素。 以下是XML文件外觀的兩個示例。

檔案1:

<?xml version="1.0" encoding="utf-8" ?>
<Sandra>
  <Address>
    <Street></Street>
    <Number></Number>
  </Address>
</Sandra>

文件2:

<?xml version="1.0" encoding="utf-8" ?>
<John>
  <Address>
    <Street></Street>
    <Number></Number>
  </Address>
</John>

我希望能夠使用2個類來序列化和反序列化,例如:

[Serializable]
[XmlRoot]
public class Person
{
    [XmlElement("Address")]
    public List<Address> Adresses { get; set; }
}

[Serializable]
public class Address
{
    public string Street { get; set; }

    public string Number { get; set; }
}

我嘗試使用以下方法閱讀它們:

    var ser = new XmlSerializer(typeof(Person));
    var reader = XmlReader.Create("person1.xml");
    var person = (Person)ser.Deserialize(reader);

但我得到"There is an error in XML document (2, 2)." ,因為反序列化器期望<"Person">根元素而不是<"John"><"Paul"> 如果我將[XmlRoot]更改為[XmlRoot("John")]它可以正常工作,但這正是我在這里要避免的。

此外,我必須能夠使用相同的奇怪XML結構將其序列化,因此我需要將根元素名稱存儲在Person類中。

我知道我可以簡單地創建自己的(de)序列化器,但我想知道是否可以使用現有方法實現它。

編輯1 :(回滾)。

編輯2:回滾“編輯1”的修改,因為我找到了一種更簡單的方法來實現我所需要的。 請參閱下面的答案。

找到了解決我問題的簡潔快捷的方法! 我只需在實例化XmlSerializer時使用XmlRootAttribute。 這樣我就可以在運行時設置根元素的名稱。

var personsName = "Sandra";
var ser = new XmlSerializer(typeof(Person), 
   new XmlRootAttribute { ElementName = personsName });
var reader = XmlReader.Create("person1.xml");
var person = (Person)ser.Deserialize(reader);

當然,如果我想序列化它也會以相同的方式工作。

使用人名作為XML元素名稱感覺有點不穩定。 每個元素代表什么, JohnPerson

如果您能夠控制這些XML文件的形狀,可能會更好地表示它們:

<?xml version="1.0" encoding="utf-8" ?>
<Person name="Sandra">
  <Address>
    <Street></Street>
    <Number></Number>
  </Address>
</Person>

然后,您將有一種簡單的方法將名稱存儲在屬性中,映射為XML屬性:

[Serializable]
[XmlRoot]
public class Person
{
    [XmlElement("Address")]
    public List<Address> Adresses { get; set; }

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

在您的類中實現IXmlSerializable並按照您希望的方式進行序列化:

ReadXml(System.Xml.XmlReader reader)WriteXml(System.Xml.XmlWriter writer)

例如:

[Serializable]
public class Threshold : IXmlSerializable
{

public int Type {get;set;}
public object Value {get;set;}
public string Name {get;set;}
public void ReadXml(System.Xml.XmlReader reader)
{


XElement thresholdXML = XElement.Load(reader);

if (!thresholdXML.HasElements || thresholdXML.IsEmpty)
return;

Type = (ThresholdType)int.Parse(thresholdXML.Element("Type").Value);
Value = Type.Equals(ThresholdType.Complex) ? thresholdXML.Element("Value").Value : (object)Decimal.Parse(thresholdXML.Element("Value").Value);
Name = thresholdXML.Element("Name").Value;


}


public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}

public void WriteXml(System.Xml.XmlWriter writer)
{
XmlSerializerNamespaces xmlnsEmpty = new XmlSerializerNamespaces();
xmlnsEmpty.Add("", "");


writer.WriteElementString("Type", ((int)Type).ToString("D"));
writer.WriteElementString("Value", Value.ToString());
writer.WriteElementString("Name", Name);
}
}

使用root元素作為ArrayOfClassName,然后嘗試它。

<ArrayOfAlarmSummary>
  <AlarmSummary>
    <ClientId>1</ClientId>
    <StationId>2</StationId>
    <StationName>Station-2</StationName>
    <DateTime>13/09/15</DateTime>
    <TagName>AI2_2</TagName>
    <Description>TR DC Current</Description>
    <Units>Amps</Units>
    <NormalOperation>10 to 100</NormalOperation>
    <AlarmValue>132.48</AlarmValue>
    <AlarmDescription>
    </AlarmDescription>
  </AlarmSummary>
  <AlarmSummary>
    <ClientId>1</ClientId>
    <StationId>2</StationId>
    <StationName>Station-2</StationName>
    <DateTime>13/09/15</DateTime>
    <TagName>AI2_2</TagName>
    <Description>TR AC Current</Description>
    <Units>Amps</Units>
    <NormalOperation>10 to 100</NormalOperation>
    <AlarmValue>132.48</AlarmValue>
    <AlarmDescription>
    </AlarmDescription>
  </AlarmSummary>
</ArrayOfAlarmSummary>

這是反序列化類,使用它可以反序列化您的Xml文件。

 public class SerializeDeserialize<T>
    {
        StringBuilder sbData;
        StringWriter swWriter;
        XmlDocument xDoc;
        XmlNodeReader xNodeReader;
        XmlSerializer xmlSerializer;
        public SerializeDeserialize()
        {
            sbData = new StringBuilder();
        }
        public string SerializeData(T data)
        {
            XmlSerializer employeeSerializer = new XmlSerializer(typeof(T));
            swWriter = new StringWriter(sbData);
            employeeSerializer.Serialize(swWriter, data);
            return sbData.ToString();
        }

        public T DeserializeData(string dataXML)
        {
            xDoc = new XmlDocument();
            xDoc.LoadXml(dataXML);
            xNodeReader = new XmlNodeReader(xDoc.DocumentElement);
            xmlSerializer = new XmlSerializer(typeof(T));
            var employeeData = xmlSerializer.Deserialize(xNodeReader);
            T deserializedEmployee = (T)employeeData;
            return deserializedEmployee;
        }
    }

打電話給班級

 var appDomain = System.IO.Directory.GetCurrentDirectory() + "\\AlarmFiles";
            var strPath = Path.Combine(appDomain,
                "Alarm_" + DateTime.Now.ToString("ddMMyyyy") + Constants.FileType.XmlFile);
            var fi = new FileInfo(strPath);
            if (fi.Exists)
            {
                try
                {
                    var xmlString = System.IO.File.ReadAllText(strPath);
                    var serializeAlarmSummary =
                        new SerializeDeserialize<List<AlarmSummary>>();
                    return serializeAlarmSummary.DeserializeData(xmlString);
                }
                catch (Exception ex)
                {
                    throw ex;
                }

            }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM