Xml序列化动态忽略

发布于 2024-11-15 21:03:28 字数 1062 浏览 4 评论 0原文

我正在尝试生成特定格式的 xml 文档。我想根据属性的值跳过序列化属性。

public class Parent
{
    public Parent()
    {
        myChild = new Child();
        myChild2 = new Child() { Value = "Value" };
    }
    public Child myChild { get; set; }
    public Child myChild2 { get; set; }
}

public class Child
{
    private bool _set;
    public bool Set { get { return _set; } }

    private string _value = "default";
    [System.Xml.Serialization.XmlText()]
    public string Value
    {
        get { return _value; }
        set { _value = value; _set = true; }
    }
}

System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(Parent));
x.Serialize(Console.Out, new Parent());

如果 Set 为 false,我希望整个属性不被序列化,我生成的 xml 应该是

<Parent>
   <myChild2>default</myChild2>
</Parent>

而不是

<Parent>
   <myChild/>
   <myChild2>default</myChild2>
</Parent>

有什么方法可以使用 IXmlSerialized 或其他任何方式干净地完成此操作吗?

谢谢!

I am trying to generate an xml document in a specific format. I would like to skip serializing a property depending on a value of the property.

public class Parent
{
    public Parent()
    {
        myChild = new Child();
        myChild2 = new Child() { Value = "Value" };
    }
    public Child myChild { get; set; }
    public Child myChild2 { get; set; }
}

public class Child
{
    private bool _set;
    public bool Set { get { return _set; } }

    private string _value = "default";
    [System.Xml.Serialization.XmlText()]
    public string Value
    {
        get { return _value; }
        set { _value = value; _set = true; }
    }
}

System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(Parent));
x.Serialize(Console.Out, new Parent());

If Set is false, I want the entire property to not be serialized, my resulting xml should be

<Parent>
   <myChild2>default</myChild2>
</Parent>

Instead of

<Parent>
   <myChild/>
   <myChild2>default</myChild2>
</Parent>

Is there some way I can do this cleanly with IXmlSerializable or anything else?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

避讳 2024-11-22 21:03:28

有一个 ShouldSerialize* 模式(由 TypeDescriptor 引入,但被其他一些代码区域识别,例如 XmlSerializer):

public bool ShouldSerializemyChild() {
     return myChild != null && myChild.Set;
}

应该对其进行排序。

不过,一个更简单的选择是将其分配为空。

There is a ShouldSerialize* pattern (introduced by TypeDescriptor, but recognised by a few other areas of code, such as XmlSerializer):

public bool ShouldSerializemyChild() {
     return myChild != null && myChild.Set;
}

That should sort it.

A simpler option, though, is to assign it null.

情独悲 2024-11-22 21:03:28

如果“mychild”是由数组定义的,我认为它可以做得很好......

public class Parent
{
    public Parent()
    {
        myChild = new Child[]{ new Child(){Value = "Value"}};
        //myChild2 = new Child() { Value = "Value" };
    }
    public Child[] myChild { get; set; }
    //public Child myChild2 { get; set; }
}

If "mychild" is defined by the array , i think it can do well...

public class Parent
{
    public Parent()
    {
        myChild = new Child[]{ new Child(){Value = "Value"}};
        //myChild2 = new Child() { Value = "Value" };
    }
    public Child[] myChild { get; set; }
    //public Child myChild2 { get; set; }
}
小矜持 2024-11-22 21:03:28

我认为这可行,尽管您可能必须覆盖 Equals 方法

[DefaultValue(new Child())]
public Child myChild{ get; set; }

I think this could work, though you migh have to overide the Equals method

[DefaultValue(new Child())]
public Child myChild{ get; set; }
两相知 2024-11-22 21:03:28

编写这段代码只是为了好玩,也许可以在这个过程中学到一些东西。
如果任何属性包含返回 bool 的称为 Set 的方法,并且其当前值为 false,则应将该属性设置为 null。通过将值设置为 false,应该可以解决序列化器问题。
任何建议:

public static void RemoveUnsetObjects(object currentObject)
{
    var type = currentObject.GetType();
    if (currentObject is IEnumerable)
    {
        IEnumerable list = (currentObject as IEnumerable);
        foreach (object o in list)
        {
            RemoveUnsetObjects(o);
        }
    }
    else
    {
        foreach (var p in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
        {
            var propertyValue = p.GetValue(currentObject, null);
            if (propertyValue == null)
                continue;
                    var setPropInfo = p.PropertyType.GetProperty("Set", typeof(bool));
            if (setPropInfo != null)
            {
                var isSet = (bool)setPropInfo.GetValue(propertyValue, null);
                if (!isSet)
                {
                    p.SetValue(currentObject, null, null);
                }
            }
            else
            {
                RemoveUnsetObjects(propertyValue);
            }
        }
    }
}

Just wrote this code for fun and maybe learn something in the process.
It should set any property to null if that property contains a method called Set that returns bool, and its current value is false. By setting the values to false, it should solve the serializer issue.
Any suggestions:

public static void RemoveUnsetObjects(object currentObject)
{
    var type = currentObject.GetType();
    if (currentObject is IEnumerable)
    {
        IEnumerable list = (currentObject as IEnumerable);
        foreach (object o in list)
        {
            RemoveUnsetObjects(o);
        }
    }
    else
    {
        foreach (var p in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
        {
            var propertyValue = p.GetValue(currentObject, null);
            if (propertyValue == null)
                continue;
                    var setPropInfo = p.PropertyType.GetProperty("Set", typeof(bool));
            if (setPropInfo != null)
            {
                var isSet = (bool)setPropInfo.GetValue(propertyValue, null);
                if (!isSet)
                {
                    p.SetValue(currentObject, null, null);
                }
            }
            else
            {
                RemoveUnsetObjects(propertyValue);
            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文