C# XML属性的选择性序列化
这是一项正在进行的工作。我正在开发这些C#类来序列化XML数据:C# XML属性的选择性序列化,c#,xmlserializer,C#,Xmlserializer,这是一项正在进行的工作。我正在开发这些C#类来序列化XML数据: using SimpleLogger; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Xml.Serialization; namespace MSAToolsLibrary.SRRAssignmentHis
using SimpleLogger;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Xml.Serialization;
namespace MSAToolsLibrary.SRRAssignmentHistory
{
[Guid("xxx")]
[ComVisible(true)]
public enum AssignmentMode
{
Weekly,
Midweek,
Weekend
}
[Guid("xxx")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[ComVisible(true)]
public interface IAssignmentHistorySRRInterface
{
void SetPathXML(String strPathXML, out Int64 iResult);
bool SaveDutyAssignmentHistory();
bool ReadDutyAssignmentHistory(out Int64 iNumberEntriesRead);
void Test();
}
public class AssignmentHistorySRR : IAssignmentHistorySRRInterface
{
private DutyAssignmentHistory _DutyAssignmentHistory;
private string _strPathXML;
public AssignmentHistorySRR()
{
_DutyAssignmentHistory = new DutyAssignmentHistory();
_strPathXML = "";
}
public void SetPathXML(string strPathXML, out Int64 iResult)
{
_strPathXML = strPathXML;
iResult = 1;
}
public bool ReadDutyAssignmentHistory(out Int64 iNumberEntriesRead)
{
bool bRead = false;
iNumberEntriesRead = 0;
try
{
_DutyAssignmentHistory.DutyAssignments.Clear(); // Reset
XmlSerializer x = new XmlSerializer(_DutyAssignmentHistory.GetType());
using (StreamReader reader = new StreamReader(_strPathXML))
{
_DutyAssignmentHistory = (DutyAssignmentHistory)x.Deserialize(reader);
_DutyAssignmentHistory.BuildDutyAssignmentDictionaryFromList();
iNumberEntriesRead = _DutyAssignmentHistory.DutyAssignments.Count;
bRead = true;
}
}
catch (Exception ex)
{
SimpleLog.Log(ex);
}
return bRead;
}
public bool SaveDutyAssignmentHistory()
{
bool bSaved = false;
try
{
_DutyAssignmentHistory.BuildDutyAssignmentListFromDictionary();
XmlSerializer x = new XmlSerializer(_DutyAssignmentHistory.GetType());
using (StreamWriter writer = new StreamWriter(_strPathXML))
{
x.Serialize(writer, _DutyAssignmentHistory);
bSaved = true;
}
}
catch (Exception ex)
{
SimpleLog.Log(ex);
}
return bSaved;
}
public void Test()
{
SetPathXML(@"d:\testsrr.xml", out long iResult);
List<int> columnindex = new List<int>();
List<string> names = new List<string>();
columnindex.Add(1);
columnindex.Add(2);
columnindex.Add(3);
columnindex.Add(4);
columnindex.Add(5);
columnindex.Add(6);
names.Add("Assign 1");
names.Add("Assign 2");
names.Add("Assign 3");
names.Add("Assign 4");
names.Add("Assign 5");
names.Add("Assign 6");
_DutyAssignmentHistory.AddAssignments("W20180101", -1, AssignmentMode.Weekly, columnindex, names);
SaveDutyAssignmentHistory();
}
}
[XmlRoot(ElementName = "DutyAssignmentHistory", Namespace = "http://www.publictalksoftware.co.uk/msa")]
public class DutyAssignmentHistory
{
public List<DutyAssignmentEntry> DutyAssignments
{
get => _DutyAssignments; set => _DutyAssignments = value;
}
private List<DutyAssignmentEntry> _DutyAssignments;
private Dictionary<string, DutyAssignmentEntry> _DutyAssignmentsDictionary = new Dictionary<string, DutyAssignmentEntry>();
public DutyAssignmentHistory()
{
_DutyAssignments = new List<DutyAssignmentEntry>();
}
public void BuildDutyAssignmentDictionaryFromList()
{
_DutyAssignmentsDictionary = _DutyAssignments.ToDictionary(x => x.Week, x => x);
}
public void BuildDutyAssignmentListFromDictionary()
{
_DutyAssignments = _DutyAssignmentsDictionary.Select(x => x.Value).ToList();
}
public void AddAssignments(string Week, int Template, AssignmentMode eMode, List<int> ColumnIndex, List<string> Names)
{
DutyAssignmentEntry oEntry = new DutyAssignmentEntry
{
Week = Week,
Template = Template,
WeeklyMode = eMode == AssignmentMode.Weekly
};
int iNumNames = Names.Count;
for(int iName = 0; iName < iNumNames; iName++)
{
Assignment oAssign = new Assignment
{
ColumnIndex = ColumnIndex[iName],
Name = Names[iName]
};
if (eMode == AssignmentMode.Midweek)
oEntry.MidweekAssignments.Add(oAssign);
else if (eMode == AssignmentMode.Weekend)
oEntry.WeekendAssignments.Add(oAssign);
else
oEntry.WeeklyAssignments.Add(oAssign);
}
_DutyAssignmentsDictionary.Add(Week, oEntry);
}
}
public class DutyAssignmentEntry
{
[XmlAttribute]
public string Week
{
get => _Week; set => _Week = value;
}
private string _Week;
[XmlAttribute]
public int Template
{
get => _Template; set => _Template = value;
}
private int _Template;
[XmlAttribute]
public bool WeeklyMode
{
get => _WeeklyMode; set => _WeeklyMode = value;
}
private bool _WeeklyMode;
public List<Assignment> MidweekAssignments
{
get => _MidweekAssignments; set => _MidweekAssignments = value;
}
private List<Assignment> _MidweekAssignments;
public List<Assignment> WeekendAssignments
{
get => _WeekendAssignments; set => _WeekendAssignments = value;
}
private List<Assignment> _WeekendAssignments;
public List<Assignment> WeeklyAssignments
{
get => _WeeklyAssignments; set => _WeeklyAssignments = value;
}
private List<Assignment> _WeeklyAssignments;
public DutyAssignmentEntry()
{
_Week = "";
_Template = -1;
_WeeklyMode = true;
_MidweekAssignments = new List<Assignment>();
_WeekendAssignments = new List<Assignment>();
_WeeklyAssignments = new List<Assignment>();
}
}
public class Assignment
{
[XmlAttribute]
public int ColumnIndex
{
get => _ColumnIndex; set => _ColumnIndex = value;
}
private int _ColumnIndex;
[XmlText]
public string Name
{
get => _Name; set => _Name = value;
}
private string _Name;
public Assignment()
{
_ColumnIndex = -1;
_Name = "";
}
}
}
当我执行上述MFC代码时,我会得到一个XML文件(正如我预期的那样),如下所示:
<?xml version="1.0" encoding="utf-8"?>
<DutyAssignmentHistory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.publictalksoftware.co.uk/msa">
<DutyAssignments>
<DutyAssignmentEntry Week="W20180101" Template="-1" WeeklyMode="true">
<MidweekAssignments />
<WeekendAssignments />
<WeeklyAssignments>
<Assignment ColumnIndex="1">Assign 1</Assignment>
<Assignment ColumnIndex="2">Assign 2</Assignment>
<Assignment ColumnIndex="3">Assign 3</Assignment>
<Assignment ColumnIndex="4">Assign 4</Assignment>
<Assignment ColumnIndex="5">Assign 5</Assignment>
<Assignment ColumnIndex="6">Assign 6</Assignment>
</WeeklyAssignments>
</DutyAssignmentEntry>
</DutyAssignments>
</DutyAssignmentHistory>
public class DutyAssignmentEntry
{
private string _Week;
private int _Template;
private bool _WeeklyMode;
private List<Assignment> _MidweekAssignments;
private List<Assignment> _WeekendAssignments;
private List<Assignment> _WeeklyAssignments;
[XmlAttribute]
public string Week
{
get => _Week; set => _Week = value;
}
[XmlAttribute]
public int Template
{
get => _Template; set => _Template = value;
}
[XmlAttribute]
public bool WeeklyMode
{
get => _WeeklyMode; set => _WeeklyMode = value;
}
public List<Assignment> MidweekAssignments
{
get => _MidweekAssignments; set => _MidweekAssignments = value;
}
[XmlIgnore]
public bool MidweekAssignmentsSpecified
{
get { return (_MidweekAssignments.Count > 0); }
}
public List<Assignment> WeekendAssignments
{
get => _WeekendAssignments; set => _WeekendAssignments = value;
}
[XmlIgnore]
public bool WeekendAssignmentsSpecified
{
get { return (_WeekendAssignments.Count > 0); }
}
public List<Assignment> WeeklyAssignments
{
get => _WeeklyAssignments; set => _WeeklyAssignments = value;
}
[XmlIgnore]
public bool WeeklyAssignmentsSpecified
{
get { return (_WeeklyAssignments.Count > 0); }
}
public DutyAssignmentEntry()
{
_Week = "";
_Template = -1;
_WeeklyMode = true;
_MidweekAssignments = new List<Assignment>();
_WeekendAssignments = new List<Assignment>();
_WeeklyAssignments = new List<Assignment>();
}
}
分配1
分配2
分配3
分配4
分配5
分配6
请注意,我有三个潜在的内部节点列表:
- 周中签字
- 周末派遣
- 周报
<?xml version="1.0" encoding="utf-8"?>
<DutyAssignmentHistory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.publictalksoftware.co.uk/msa">
<DutyAssignments>
<DutyAssignmentEntry Week="W20180101" Template="-1" WeeklyMode="true">
<MidweekAssignments />
<WeekendAssignments />
<WeeklyAssignments>
<Assignment ColumnIndex="1">Assign 1</Assignment>
<Assignment ColumnIndex="2">Assign 2</Assignment>
<Assignment ColumnIndex="3">Assign 3</Assignment>
<Assignment ColumnIndex="4">Assign 4</Assignment>
<Assignment ColumnIndex="5">Assign 5</Assignment>
<Assignment ColumnIndex="6">Assign 6</Assignment>
</WeeklyAssignments>
</DutyAssignmentEntry>
</DutyAssignments>
</DutyAssignmentHistory>
public class DutyAssignmentEntry
{
private string _Week;
private int _Template;
private bool _WeeklyMode;
private List<Assignment> _MidweekAssignments;
private List<Assignment> _WeekendAssignments;
private List<Assignment> _WeeklyAssignments;
[XmlAttribute]
public string Week
{
get => _Week; set => _Week = value;
}
[XmlAttribute]
public int Template
{
get => _Template; set => _Template = value;
}
[XmlAttribute]
public bool WeeklyMode
{
get => _WeeklyMode; set => _WeeklyMode = value;
}
public List<Assignment> MidweekAssignments
{
get => _MidweekAssignments; set => _MidweekAssignments = value;
}
[XmlIgnore]
public bool MidweekAssignmentsSpecified
{
get { return (_MidweekAssignments.Count > 0); }
}
public List<Assignment> WeekendAssignments
{
get => _WeekendAssignments; set => _WeekendAssignments = value;
}
[XmlIgnore]
public bool WeekendAssignmentsSpecified
{
get { return (_WeekendAssignments.Count > 0); }
}
public List<Assignment> WeeklyAssignments
{
get => _WeeklyAssignments; set => _WeeklyAssignments = value;
}
[XmlIgnore]
public bool WeeklyAssignmentsSpecified
{
get { return (_WeeklyAssignments.Count > 0); }
}
public DutyAssignmentEntry()
{
_Week = "";
_Template = -1;
_WeeklyMode = true;
_MidweekAssignments = new List<Assignment>();
_WeekendAssignments = new List<Assignment>();
_WeeklyAssignments = new List<Assignment>();
}
}
如果WeeklyMode设置为“Weekly”,那么WeeklyAssignments节点应该出现在XMl条目中,否则,Middweek/Weekly节点应该出现
此时,即使节点列表中没有条目,也会创建空节点。这并不重要,它可以保持这样。但是,是否可以调整代码,使其仅在有数据时读取/写入 将属性添加到属性中:
[XmlElement]
public List<Assignment> MidweekAssignments
{
get { return _MidweekAssignments; } set { _MidweekAssignments = value;}
}
private List<Assignment> _MidweekAssignments;
[XmlElement]
public List<Assignment> WeekendAssignments
{
get { return _WeekendAssignments; } set { _WeekendAssignments = value;}
}
private List<Assignment> _WeekendAssignments;
[XmlElement]
public List<Assignment> WeeklyAssignments
{
get
{ return _WeeklyAssignments; } set { _WeeklyAssignments = value;}
}
private List<Assignment> _WeeklyAssignments;
[XmlElement]
周中公开名单
{
获取{return}MidweekAssignments;}set{{u MidweekAssignments=value;}
}
私人名单(周中签署);;
[XmlElement]
公共列表周分配
{
获取{return}WeekendAssignments;}set{{WeekendAssignments=value;}
}
私人名单(每星期一次);;
[XmlElement]
公开名单周报
{
得到
{return{u WeeklyAssignments;}set{{u WeeklyAssignments=value;}
}
私人名单(每周签署);;
很抱歉,C#7语法不那么花哨,我手头只有旧的东西
这不会更改接口及其行为,但会按如下方式呈现XML:
<?xml version="1.0" encoding="utf-16"?>
<DutyAssignmentHistory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.publictalksoftware.co.uk/msa">
<DutyAssignments>
<DutyAssignmentEntry Week="W20180101" Template="-1" WeeklyMode="true">
<WeeklyAssignments ColumnIndex="1">Assign 1</WeeklyAssignments>
<WeeklyAssignments ColumnIndex="2">Assign 2</WeeklyAssignments>
<WeeklyAssignments ColumnIndex="3">Assign 3</WeeklyAssignments>
<WeeklyAssignments ColumnIndex="4">Assign 4</WeeklyAssignments>
<WeeklyAssignments ColumnIndex="5">Assign 5</WeeklyAssignments>
<WeeklyAssignments ColumnIndex="6">Assign 6</WeeklyAssignments>
</DutyAssignmentEntry>
</DutyAssignments>
</DutyAssignmentHistory>
分配1
分配2
分配3
分配4
分配5
分配6
如果我这样调整我的课程,这符合你的要求:
<?xml version="1.0" encoding="utf-8"?>
<DutyAssignmentHistory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.publictalksoftware.co.uk/msa">
<DutyAssignments>
<DutyAssignmentEntry Week="W20180101" Template="-1" WeeklyMode="true">
<MidweekAssignments />
<WeekendAssignments />
<WeeklyAssignments>
<Assignment ColumnIndex="1">Assign 1</Assignment>
<Assignment ColumnIndex="2">Assign 2</Assignment>
<Assignment ColumnIndex="3">Assign 3</Assignment>
<Assignment ColumnIndex="4">Assign 4</Assignment>
<Assignment ColumnIndex="5">Assign 5</Assignment>
<Assignment ColumnIndex="6">Assign 6</Assignment>
</WeeklyAssignments>
</DutyAssignmentEntry>
</DutyAssignments>
</DutyAssignmentHistory>
public class DutyAssignmentEntry
{
private string _Week;
private int _Template;
private bool _WeeklyMode;
private List<Assignment> _MidweekAssignments;
private List<Assignment> _WeekendAssignments;
private List<Assignment> _WeeklyAssignments;
[XmlAttribute]
public string Week
{
get => _Week; set => _Week = value;
}
[XmlAttribute]
public int Template
{
get => _Template; set => _Template = value;
}
[XmlAttribute]
public bool WeeklyMode
{
get => _WeeklyMode; set => _WeeklyMode = value;
}
public List<Assignment> MidweekAssignments
{
get => _MidweekAssignments; set => _MidweekAssignments = value;
}
[XmlIgnore]
public bool MidweekAssignmentsSpecified
{
get { return (_MidweekAssignments.Count > 0); }
}
public List<Assignment> WeekendAssignments
{
get => _WeekendAssignments; set => _WeekendAssignments = value;
}
[XmlIgnore]
public bool WeekendAssignmentsSpecified
{
get { return (_WeekendAssignments.Count > 0); }
}
public List<Assignment> WeeklyAssignments
{
get => _WeeklyAssignments; set => _WeeklyAssignments = value;
}
[XmlIgnore]
public bool WeeklyAssignmentsSpecified
{
get { return (_WeeklyAssignments.Count > 0); }
}
public DutyAssignmentEntry()
{
_Week = "";
_Template = -1;
_WeeklyMode = true;
_MidweekAssignments = new List<Assignment>();
_WeekendAssignments = new List<Assignment>();
_WeeklyAssignments = new List<Assignment>();
}
}
公共类DutyAssignmentEntry
{
私人字符串(u周),;
私有int_模板;
私人书店周刊;
私人名单(周中签署);;
私人名单(每星期一次);;
私人名单(每周签署);;
[XmlAttribute]
公共字符串周
{
获取=>\u周;设置=>\u周=值;
}
[XmlAttribute]
公共int模板
{
获取=>\u模板;设置=>\u模板=值;
}
[XmlAttribute]
公共图书馆周刊
{
get=>\u WeeklyMode;set=>\u WeeklyMode=value;
}
周中公开名单
{
get=>\u周中签名;set=>\u周中签名=值;
}
[XmlIgnore]
已指定周中公共布尔标志
{
获取{return(_MidweekAssignments.Count>0);}
}
公共列表周分配
{
get=>\u WeekendAssignments;set=>\u WeekendAssignments=value;
}
[XmlIgnore]
指定的公共业务周分配
{
获取{return(_WeekendAssignments.Count>0);}
}
公开名单周报
{
get=>\u WeeklyAssignments;set=>\u WeeklyAssignments=value;
}
[XmlIgnore]
指定的公共布尔每周签名
{
获取{return(_WeeklyAssignments.Count>0);}
}
公共义务签名条目()
{
_周=”;
_模板=-1;
_WeeklyMode=true;
_周中签名=新列表();
_WeekendAssignments=新列表();
_WeeklyAsignments=新列表();
}
}
然后我得到了想要的行为。我仍然有我的节点列表,并且只有在三个附加属性为true时才会写入节点:
指定周中设计
weekendassignments已指定
指定的每周签名