首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XMLIgnore:从子类节点中删除基类属性

XMLIgnore:从子类节点中删除基类属性
EN

Stack Overflow用户
提问于 2014-08-27 12:16:47
回答 1查看 974关注 0票数 0

在序列化时,我使用XMLIgnore属性删除不需要的属性。但是,我只想从子类中删除一些基类属性。我想要基类中的属性,但它不应该在子类节点中重复。

可以从子类节点中删除基类属性吗?

在我的代码中,我得到了以下格式的输出:当我通过XMLIgnore从基类中删除属性时。

代码语言:javascript
复制
<?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>

但实际上,我希望输出的格式如下

代码语言:javascript
复制
<?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>

我正在通过下面的代码来尝试:

代码语言:javascript
复制
[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;
            }
        }
    }
EN

回答 1

Stack Overflow用户

发布于 2014-10-30 06:56:09

假设您对基类和派生类都有控制,则可以通过为希望控制输出的每个属性XmlSerializer添加一个虚拟bool ShouldSerializeXXX()方法来实现这一点。在基类中,make方法应该返回true,而在派生类中,应该重写它以返回false

例如,假设您只想在派生类中禁止Id属性的序列化,则可以:

代码语言:javascript
复制
public class BaseClass
{
    public int Id { get; set; }

    public virtual bool ShouldSerializeId()
    {
        return true;
    }
}

public class DerivedFromBaseClass : BaseClass
{
    public override bool ShouldSerializeId()
    {
        return false;
    }
}

然后,测试:

代码语言:javascript
复制
    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如下所示:

代码语言:javascript
复制
<?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

代码语言:javascript
复制
<?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" />

正如您所看到的,XML中仅针对派生类抑制了Id,我认为这就是您所要求的。

不过,我认为这里的对象模型可能并不理想。如果基类中有不应出现在派生类中的属性,则建议提取一个更通用、更抽象的基类:

代码语言:javascript
复制
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
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25527001

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档