我正在使用XMLIgnore属性来删除序列化中不需要的属性。但是我想从子类中删除一些基类属性。我想从基类中获取属性,但不应在子类节点中重复。
是否可以从子类节点中删除基类属性?
在我的代码中,我得到格式以下的输出:当我通过XMLIgnore从基类中删除属性时。
<?xml version="1.0" encoding="utf-8"?>
<InformationCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<projects>
<Project xsi:type="Group">
<GroupName>Accounts</GroupName>
<Comment>Financial Transaction</Comment>
</Project>
</projects>
</InformationCollection>
但实际上我希望输出低于格式
<?xml version="1.0" encoding="utf-8"?>
<InformationCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<projects>
<ProjectId>1</ProjectId>
<ProjectName>HRMS</ProjectName>
<Project xsi:type="Group">
<GroupName>Accounts</GroupName>
<Comment>Financial Transaction</Comment>
</Project>
</projects>
</InformationCollection>
我正在尝试以下代码:
[XmlInclude(typeof(Group))]
public class Project
{
public int ProjectId { get; set; }
public string ProjectName { get; set; }
public Project() { }
public Project(int projectId, string projectName)
{
ProjectId = projectId;
ProjectName = projectName;
}
}
public class Group : Project
{
public string GroupName;
public string Comment;
public Group():base() { }
public Group(int projectId, string projectName)
: base(projectId, projectName)
{
}
public Group(int projectId, string projectName, string groupName, string comment)
: this(projectId, projectName)
{
GroupName = groupName;
Comment = comment;
}
}
public class InformationCollection
{
public List<Project> projects = new List<Project>();
public InformationCollection()
{
projects.Add(new Group(1,"HRMS","Accounts","Financial Transaction"));
}
}
class Program
{
static void Main(string[] args)
{
SerializeObject("IgnoreXml.xml");
}
public static XmlSerializer CreateOverrider()
{
XmlAttributeOverrides xOver = new XmlAttributeOverrides();
XmlAttributes attrs = new XmlAttributes();
attrs.XmlIgnore = true;
xOver.Add(typeof(Project), "ProjectName", attrs);
xOver.Add(typeof(Project), "ProjectId", attrs);
XmlSerializer xSer = new XmlSerializer(typeof(InformationCollection), xOver);
return xSer;
}
public static void SerializeObject(string filename)
{
try
{
XmlSerializer xSer = CreateOverrider();
InformationCollection informationCollection = new InformationCollection();
TextWriter writer = new StreamWriter(filename);
xSer.Serialize(writer, informationCollection);
writer.Close();
}
catch (Exception ex)
{
throw;
}
}
}
答案 0 :(得分:1)
假设您已控制基类和派生类,可以通过为要为其控制输出的每个属性XmlSerializer
添加虚拟bool ShouldSerializeXXX()
方法,使用XXX
执行此操作。在基类中,make方法应该返回true
,并且在派生类中,应该重写它以返回false
。
例如,假设您只想在派生类中禁止Id
属性的序列化,您可以这样做:
public class BaseClass
{
public int Id { get; set; }
public virtual bool ShouldSerializeId()
{
return true;
}
}
public class DerivedFromBaseClass : BaseClass
{
public override bool ShouldSerializeId()
{
return false;
}
}
然后,测试:
public static void TestSuppressingPropertyInDerivedClass()
{
var baseClass = new BaseClass() { Id = 31 };
var derivedClass = new DerivedFromBaseClass { Id = 31 };
var baseXml = baseClass.GetXml();
// Xml looks like
Debug.Assert(baseXml.Contains("Id")); // No assert
var derivedXml = derivedClass.GetXml();
Debug.Assert(!derivedXml.Contains("Id")); // no assert.
}
BaseClass
的输出XML如下所示:
<?xml version="1.0" encoding="utf-16"?>
<BaseClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Id>31</Id>
</BaseClass>
对于DerivedFromBaseClass
:
<?xml version="1.0" encoding="utf-16"?>
<DerivedFromBaseClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
正如您所看到的,Id
仅在派生类的XML中被抑制,我认为,这就是您要求的内容。
但是,不过,我认为你的对象模型可能并不理想。如果基类中的属性不应出现在派生类中,则表明您应该提取更通用的抽象基类:
public abstract class AbstractProject {
{
// Properties common to "Group" and "Project"
}
public class Project : AbstractProject {
{
// Properties specific to Project
}
public class Group : AbstractProject {
{
// Properties specific to Group
}