带条件的xml序列化

时间:2015-01-05 17:02:57

标签: c# xml xml-serialization xmlserializer

我在序列化中有以下类:

[XmlRoot()]
public class XmlExample
{
private NodeA_Elem _nodea;
[XmlElemnt("NodeA")]
public NodeA_Elem NodeA
{
    get
    {
        return _nodea;
    }
    set
    {
        _nodea=value;
    }
}

private NodeB_Elem _nodeb;
[XmlElemnt("NodeB")]
public NodeB_Elem NodeB
{
    get
    {
        return _nodeb;
    }
    set
    {
        _nodeb=value;
    }
}

private NodeC_Elem _nodec;
[XmlElemnt("NodeC")]
public NodeC_Elem NodeC
{
    get
    {
        return _nodec;
    }
    set
    {
        _nodec=value;
    }
}
public class NodeA_Elem
{
    [XmlText()]
    public string value{get;set;}
}

public class NodeB_Elem
{
    [XmlText()]
    public string value{get;set;}
}

public class NodeC_Elem
{
    [XmlText()]
    public string value{get;set;}
}

如果NodaA,NodeB或NodeC的任何类的value属性为null或为空,我会得到以下结果:

<XmlExample>
   <NodeA/>
   <NodeB/>
   <NodeC/>
</XmlExample>

如果我没有设置value属性,我必须对这些节点做些什么不像空节点?

3 个答案:

答案 0 :(得分:2)

您可以使用ShouldSerialize *模式,如下所示: -

public bool ShouldSerializeNodeA() {
    return NodeA != null;
}

请参阅: - Conditional xml serialization

<强>更新

使其不可为空: -

[XmlElement(IsNullable = false)]

修改

前面我提到过: -

public bool ShouldSerializeNodeA() {
    return NodeB != null;
}

我的错误,它应该是这样的: -

public bool ShouldSerializeNodeA() {
    return NodeA != null;
}

答案 1 :(得分:1)

您还可以使用带有后缀x Specified的布尔属性来指示是否序列化属性。这是由使用xml的Xml客户端使用的,这些客户端具有默认值(例如,在XSD中使用default=xxx指定):

public bool NodeASpecified
{
    get { return _nodea != null && !String.IsNullOrEmpty(_nodea.value); }
}

请勿使用任何Xml属性标记这些Specified属性。

不相关,但如果您使用了具有默认值和*Specified的Web服务,则在部分类中将true属性硬编码为minOccurs=0非常有用,否则如果该值与默认值恰好相同,则根本不会发送给该服务。

答案 2 :(得分:0)

我添加了一些评论并找到了解决方案。我可以在我的代码中使用ShouldSerialize模式。生成的代码是:

[XmlRoot()]
public class XmlExample
{
    private NodeA_Elem _nodea;
    [XmlElemnt("NodeA")]
    public NodeA_Elem NodeA
    {
        get
        {
            return _nodea;
        }
        set
        {
            _nodea=value;
        }
    }
    public bool ShouldSerializeNodeA()
    {
        return !String.IsNullOrEmpty(_nodea.value);
    }

    private NodeB_Elem _nodeb;
    [XmlElemnt("NodeB")]
    public NodeB_Elem NodeB
    {
        get
        {
            return _nodeb;
        }
        set
        {
            _nodeb=value;
        }
    }
    public bool ShouldSerializeNodeB()
    {
        return !String.IsNullOrEmpty(_nodeb.value);
    }
    private NodeC_Elem _nodec;
    [XmlElemnt("NodeC")]
    public NodeC_Elem NodeC
    {
        get
        {
            return _nodec;
        }
        set
        {
            _nodec=value;
        }
    }
    public bool ShouldSerializeNodeC()
    {
        return !String.IsNullOrEmpty(_nodec.value);
    }
}

public class NodeA_Elem
{
    [XmlText()]
    public string value{get;set;}
}

public class NodeB_Elem
{
    [XmlText()]
    public string value{get;set;}
}

public class NodeC_Elem
{
    [XmlText()]
    public string value{get;set;}
}

编辑:

以下是我的示例的完整代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace Serialization_Example
{
    class Program
    {
        static void Main(string[] args)
        {
            MyXmlDocument document = new MyXmlDocument();
            document.MyExample.NodeA.value = "Value To Node A";
            document.MyExample.NodeC.value = "Value To Node C";
            document.WriteToXml(@"C:\Users\user_Name\Desktop\mydocument.xml");
        }
    }

    [XmlRoot("xmlExample")]
    public class XmlExample
    {
        private NodeA_Elem _nodea;
        [XmlElement()]
        public NodeA_Elem NodeA
        {
            get
            {
                return _nodea;
            }
            set
            {
                _nodea = value;
            }
        }
        public bool ShouldSerializeNodeA()
        {
            return !String.IsNullOrEmpty(_nodea.value);
        }

        private NodeB_Elem _nodeb;
        [XmlElement("NodeB")]
        public NodeB_Elem NodeB
        {
            get
            {
                return _nodeb;
            }
            set
            {
                _nodeb = value;
            }
        }
        public bool ShouldSerializeNodeB()
        {
            return !String.IsNullOrEmpty(_nodeb.value);
        }
        private NodeC_Elem _nodec;
        [XmlElement("NodeC")]
        public NodeC_Elem NodeC
        {
            get
            {
                return _nodec;
            }
            set
            {
                _nodec = value;
            }
        }
        public bool ShouldSerializeNodeC()
        {
            return !String.IsNullOrEmpty(_nodec.value);
        }

        public XmlExample()
        {
            _nodea = new NodeA_Elem();
            _nodeb = new NodeB_Elem();
            _nodec = new NodeC_Elem();
        }
    }

    public class NodeA_Elem
    {
        [XmlText()]
        public string value { get; set; }
    }

    public class NodeB_Elem
    {
        [XmlText()]
        public string value { get; set; }
    }

    public class NodeC_Elem
    {
        [XmlText()]
        public string value { get; set; }
    }

    public class MyXmlDocument
    {
        private XmlExample _myexample;
        public XmlExample MyExample
        {
            get
            {
                return _myexample;
            }
            set
            {
                _myexample = value;
            }
        }

        public void WriteToXml(string path)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(XmlExample));

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.Encoding = Encoding.Unicode;

            StringWriter txtwriter = new StringWriter();
            XmlWriter xmlwtr = XmlWriter.Create(txtwriter, settings);
            serializer.Serialize(xmlwtr, MyExample);

            StreamWriter writer = new StreamWriter(path);
            writer.Write(txtwriter.ToString());

            writer.Close();
        }

        public MyXmlDocument()
        {
            _myexample = new XmlExample();
        }
    }
}

如果你编译它,你会发现如果我没有设置NodeB.value的值,它就不会像以前那样生成一个空节点。