序列化列表<>导致双标签

时间:2012-11-19 14:52:57

标签: c# list serialization

附上以下文件:

facility.xsd
facilities_v1.designer.cs (generated from facility.xsd)
facilites.xml (sample output)
facilites_wish.xml (expected output)
test.cs (contains a method which is used to create some sample objects and the serialisation) 

https://dl.dropbox.com/u/481455/fac.zip

序列化工作查找,但结果与我预期的不同:

列表被序列化"两次" (请参阅facilities.xml)。预期结果在facilities_wish.xml

中实现

facilities.xsd:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="facilities_v1.dtd" xmlns:wmh="http://www.wmhelp.com/2003/eGenerator" elementFormDefault="qualified" targetNamespace="facilities_v1.dtd">
  <xs:element name="facilities">
    <xs:annotation>
      <xs:documentation> $Id$ </xs:documentation>
      <xs:documentation> ============================================================ </xs:documentation>
      <xs:documentation> For further information or questions, please contact
     Michael Balmer, balmermi at inf dot ethz dot ch </xs:documentation>
      <xs:documentation> ============================================================ </xs:documentation>
    </xs:annotation>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="facility" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string"/>
      <xs:attribute name="aggregation_layer" type="xs:string"/>
      <xs:attribute name="lang" type="xs:string" default="de-CH"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="facility">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="activity" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="id" type="xs:string" use="required"/>
      <xs:attribute name="x" type="xs:string" use="required"/>
      <xs:attribute name="y" type="xs:string" use="required"/>
      <xs:attribute name="desc" type="xs:string"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="activity">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="capacity" minOccurs="0"/>
        <xs:element ref="opentime" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="type" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="capacity">
    <xs:complexType>
      <xs:attribute name="value" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="opentime">
    <xs:complexType>
      <xs:attribute name="day" default="wk">
        <xs:simpleType>
          <xs:restriction base="xs:NMTOKEN">
            <xs:enumeration value="mon"/>
            <xs:enumeration value="tue"/>
            <xs:enumeration value="wed"/>
            <xs:enumeration value="thu"/>
            <xs:enumeration value="fri"/>
            <xs:enumeration value="sat"/>
            <xs:enumeration value="sun"/>
            <xs:enumeration value="wkday"/>
            <xs:enumeration value="wkend"/>
            <xs:enumeration value="wk"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="start_time" type="xs:string" use="required"/>
      <xs:attribute name="end_time" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>

序列化程序类:

{
    using System;
    using System.Diagnostics;
    using System.Xml.Serialization;
    using System.Collections;
    using System.Xml.Schema;
    using System.ComponentModel;
    using System.Collections.Generic;


    public partial class facilities
    {

        private List<facility> facilityField;

        private string nameField;

        private string aggregation_layerField;

        private string langField;

        public facilities()
        {
            this.facilityField = new List<facility>();
            this.langField = "de-CH";
        }

        public List<facility> facility
        {
            get
            {
                return this.facilityField;
            }
            set
            {
                this.facilityField = value;
            }
        }

        public string name
        {
            get
            {
                return this.nameField;
            }
            set
            {
                this.nameField = value;
            }
        }

        public string aggregation_layer
        {
            get
            {
                return this.aggregation_layerField;
            }
            set
            {
                this.aggregation_layerField = value;
            }
        }

        [System.ComponentModel.DefaultValueAttribute("de-CH")]
        public string lang
        {
            get
            {
                return this.langField;
            }
            set
            {
                this.langField = value;
            }
        }
    }

    public partial class facility
    {

        private List<activity> activityField;

        private string idField;

        private string xField;

        private string yField;

        private string descField;

        public facility()
        {
            this.activityField = new List<activity>();
        }

        public List<activity> activity
        {
            get
            {
                return this.activityField;
            }
            set
            {
                this.activityField = value;
            }
        }

        public string id
        {
            get
            {
                return this.idField;
            }
            set
            {
                this.idField = value;
            }
        }

        public string x
        {
            get
            {
                return this.xField;
            }
            set
            {
                this.xField = value;
            }
        }

        public string y
        {
            get
            {
                return this.yField;
            }
            set
            {
                this.yField = value;
            }
        }

        public string desc
        {
            get
            {
                return this.descField;
            }
            set
            {
                this.descField = value;
            }
        }
    }

    public partial class activity
    {

        private capacity capacityField;

        private List<opentime> opentimeField;

        private string typeField;

        public activity()
        {
            this.opentimeField = new List<opentime>();
            this.capacityField = new capacity();
        }

        public capacity capacity
        {
            get
            {
                return this.capacityField;
            }
            set
            {
                this.capacityField = value;
            }
        }

        public List<opentime> opentime
        {
            get
            {
                return this.opentimeField;
            }
            set
            {
                this.opentimeField = value;
            }
        }

        public string type
        {
            get
            {
                return this.typeField;
            }
            set
            {
                this.typeField = value;
            }
        }
    }

    public partial class capacity
    {

        private string valueField;

        public string value
        {
            get
            {
                return this.valueField;
            }
            set
            {
                this.valueField = value;
            }
        }
    }

    public partial class opentime
    {

        private opentimeDay dayField;

        private string start_timeField;

        private string end_timeField;

        public opentime()
        {
            this.dayField = opentimeDay.wk;
        }

        [System.ComponentModel.DefaultValueAttribute(opentimeDay.wk)]
        public opentimeDay day
        {
            get
            {
                return this.dayField;
            }
            set
            {
                this.dayField = value;
            }
        }

        public string start_time
        {
            get
            {
                return this.start_timeField;
            }
            set
            {
                this.start_timeField = value;
            }
        }

        public string end_time
        {
            get
            {
                return this.end_timeField;
            }
            set
            {
                this.end_timeField = value;
            }
        }
    }

    public enum opentimeDay
    {

        /// <remarks/>
        mon,

        /// <remarks/>
        tue,

        /// <remarks/>
        wed,

        /// <remarks/>
        thu,

        /// <remarks/>
        fri,

        /// <remarks/>
        sat,

        /// <remarks/>
        sun,

        /// <remarks/>
        wkday,

        /// <remarks/>
        wkend,

        /// <remarks/>
        wk,
    }
}

示例输出:

<?xml version="1.0" encoding="utf-8"?>
<facilities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <facility>
    <facility>
      <activity>
        <activity>
          <capacity>
            <value>10000</value>
          </capacity>
          <opentime />
          <type>accommodation</type>
        </activity>
      </activity>
      <id>AC5</id>
      <x>1,5</x>
      <y>1,5</y>
      <desc>IOC Bus Hub</desc>
    </facility>
    <facility>
      <activity>
        <activity>
          <capacity>
            <value>198</value>
          </capacity>
          <opentime>
            <opentime>
              <day>sat</day>
              <start_time>16:00</start_time>
              <end_time>21:30</end_time>
            </opentime>
          </opentime>
          <type>605_ATH</type>
        </activity>
        <activity>
          <capacity>
            <value>380</value>
          </capacity>
          <opentime>
            <opentime>
              <day>sat</day>
              <start_time>12:30</start_time>
              <end_time>23:00</end_time>
            </opentime>
          </opentime>
          <type>605_MPB</type>
        </activity>
        <activity>
          <capacity>
            <value>380</value>
          </capacity>
          <opentime>
            <opentime>
              <day>sat</day>
              <start_time>15:30</start_time>
              <end_time>00:00</end_time>
            </opentime>
          </opentime>
          <type>605_MPP</type>
        </activity>
        <activity>
          <capacity>
            <value>95</value>
          </capacity>
          <opentime>
            <opentime>
              <day>sat</day>
              <start_time>12:45</start_time>
              <end_time>22:00</end_time>
            </opentime>
          </opentime>
          <type>605_OBO</type>
        </activity>
        <activity>
          <capacity>
            <value>1061</value>
          </capacity>
          <opentime>
            <opentime>
              <day>sat</day>
              <start_time>13:00</start_time>
              <end_time>00:00</end_time>
            </opentime>
          </opentime>
          <type>605_WF</type>
        </activity>
        <activity>
          <capacity>
            <value>380</value>
          </capacity>
          <opentime>
            <opentime>
              <day>sat</day>
              <start_time>16:15</start_time>
              <end_time>21:00</end_time>
            </opentime>
          </opentime>
          <type>605_OF</type>
        </activity>
        <activity>
          <capacity>
            <value>5000</value>
          </capacity>
          <opentime>
            <opentime>
              <day>sat</day>
              <start_time>15:15</start_time>
              <end_time>21:30</end_time>
            </opentime>
          </opentime>
          <type>605_SPE</type>
        </activity>
        <activity>
          <capacity>
            <value>1000</value>
          </capacity>
          <opentime>
            <opentime>
              <day>sat</day>
              <start_time>15:30</start_time>
              <end_time>21:00</end_time>
            </opentime>
          </opentime>
          <type>605_SPO</type>
        </activity>
        <activity>
          <capacity>
            <value>11</value>
          </capacity>
          <opentime>
            <opentime>
              <day>sat</day>
              <start_time>14:30</start_time>
              <end_time>22:00</end_time>
            </opentime>
          </opentime>
          <type>605_TO</type>

希望输出:

<?xml version="1.0" encoding="utf-8"?>
<facilities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <facility>      
        <activity>
          <capacity>
            <value>10000</value>
          </capacity>
          <opentime />
          <type>accommodation</type>
        </activity>

      <id>AC5</id>
      <x>1,5</x>
      <y>1,5</y>
      <desc>IOC Bus Hub</desc>
    </facility>
    <facility>
        <activity>
          <capacity>
            <value>198</value>
          </capacity>
          <opentime>
            <opentime>
              <day>sat</day>
              <start_time>16:00</start_time>
              <end_time>21:30</end_time>
            </opentime>
          </opentime>
          <type>605_ATH</type>
        </activity>
        <activity>
          <capacity>
            <value>380</value>
          </capacity>
          <opentime>
            <opentime>
              <day>sat</day>
              <start_time>12:30</start_time>
              <end_time>23:00</end_time>
            </opentime>
          </opentime>
          <type>605_MPB</type>
        </activity>
    </facility>
</facilities>

Object Creation:

 [TestMethod]
        public void TestAlex()
        {
            var hashFacilities = new Hashtable();

            var facXlsx = new Workbook(ConfigSettings.ReadSetting("facilitiesXLSX"));
            Worksheet wFacilities = facXlsx.Worksheets["Tabelle2"];

            for (int i = 3; i < wFacilities.Cells.Rows.Count; i++)
            {
                Row row = wFacilities.Cells.Rows[i];

                string valName = row.GetCellByIndex(0).StringValue;
                string valAggregationlayer = row.GetCellByIndex(1).StringValue;
                string valLang = row.GetCellByIndex(2).StringValue;
                string valId = row.GetCellByIndex(3).StringValue;
                string valX = row.GetCellByIndex(4).StringValue;
                string valY = row.GetCellByIndex(5).StringValue;
                string valDesc = row.GetCellByIndex(6).StringValue;
                string valType = row.GetCellByIndex(7).StringValue;
                string valValue = row.GetCellByIndex(8).StringValue;
                string valDay = row.GetCellByIndex(9).StringValue;
                string valStartTime = row.GetCellByIndex(10).StringValue;
                string valEndTime = row.GetCellByIndex(11).StringValue;

                if (hashFacilities.ContainsKey(valId))
                {
                    var fac = (facility) hashFacilities[valId];
                    AttachActivity(valType, valValue, valDay, valStartTime, valEndTime, fac);
                }
                else
                {
                    var fac = new facility {id = valId, desc = valDesc, x = valX, y = valY};
                    AttachActivity(valType, valValue, valDay, valStartTime, valEndTime, fac);
                    hashFacilities.Add(valId, fac);
                }
            }

            var facilities = new facilities();
            facilities.facility.AddRange(hashFacilities.Values.Cast<facility>().ToList());

            var writer = new XmlSerializer(typeof (facilities));
            var file = new StreamWriter(@"c:\temp\facilities.xml");
            writer.Serialize(file, facilities);
            file.Close();
        }

        private static void AttachActivity(string valType, string valValue, string valDay, string valStartTime,
                                           string valEndTime,
                                           facility fac)
        {
            var activity = new activity {type = valType, capacity = new capacity {value = valValue}};

            if (!string.IsNullOrEmpty(valDay) && !string.IsNullOrEmpty(valStartTime) &&
                !string.IsNullOrEmpty(valEndTime))
            {
                var time = new opentime();

                opentimeDay day;
                Enum.TryParse(valDay, true, out day);
                time.day = day;

                time.start_time = valStartTime;
                time.end_time = valEndTime;

                activity.opentime = new List<opentime> {time};
            }

            if (fac.activity != null)
            {
                fac.activity.Add(activity);
            }
            else
            {
                fac.activity = new List<activity> {activity};
            }
        }
    }
</xs:schema>

出了什么问题?

1 个答案:

答案 0 :(得分:1)

您获得的结果是因为facilities对象具有facility属性,其中包含facility个对象的列表。所以它正确地输出了一个准确的类地图。同样,您的facility类具有activity属性,该属性具有activity个对象的列表,因此它正在输出该对象。

您最好的选择就是重命名facilityactivity属性以表明它们是列表 - &gt; facilityListactivityList,并更新XSD以匹配。

如果这不是一个选项,则需要调整序列化代码以仅序列化列表属性,而不是序列化整个类。您可能需要实现与here相关的自定义序列化选项。