C# - XML序列化:省略XML输出中的某个元素

时间:2016-12-02 08:12:04

标签: c# xml xml-serialization

我在这里有一个奇怪的XML设置:我需要与第三方接口,他们使用的XML布局是我无法控制的 - 没有机会改变任何东西......

在更大的XML范围内,我发现自己需要序列化(后来也反序列化)项目列表(对于移动设备),这些项目被定义为具有Type和{{1}属性(两个字符串)。所以这就像是:

Number

这会通常public class SerialNumber { public string Type { get; set; } public string Number { get; set; } } 序列化为

List<SerialNumber> SerialNumbers

但是,就我而言,我需要发送这个XML:

<SerialNumbers>
    <SerialNumber>
        <Type>SN</Type>
        <Number>CBS583ABC123</Number>
    </SerialNumber>
    <SerialNumber>
        <Type>IMEI</Type>
        <Number>35-924106-659945-4</Number>
    </SerialNumber>
</SerialNumbers>        

基本上,列表元素需要省略 - 我只需要一个容器<SerialNumbers> <Type>SN</Type> <Number>CBS583ABC123</Number> <Type>IMEI</Type> <Number>35-924106-659945-4</Number> </SerialNumbers> ,然后对于列表中的每个条目,我只需要序列化<SerialNumbers>和{{1}子元素。

如何使用Type在.NET中轻松完成此操作?

我尝试使用

Number

XmlSerializer

但这些都不起作用 - 我仍然使用[XmlRoot(ElementName="")] public class SerialNumber 容器内的[XmlArray] [XmlArrayItem(ElementName = "")] public List<SerialNumber> SerialNumbers { get; set; } 元素获取完整序列化...

有没有一个简单的技巧来实现我正在寻找的东西?我非常宁愿进入低级别,并开始手动将我的XML拼凑在一起....

谢谢!

2 个答案:

答案 0 :(得分:2)

您可以将自定义序列化与IXmlSerializable一起使用。

public class SerialNumbers : List<SerialNumber>, IXmlSerializable
{
    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        Clear();
        reader.ReadStartElement();
        while (reader.NodeType != XmlNodeType.EndElement)
        {
            var serialNumber = new SerialNumber
            {
                Type = reader.ReadElementContentAsString("Type", ""),
                Number = reader.ReadElementContentAsString("Number", "")
            };
            Add(serialNumber);
        }
        reader.ReadEndElement();
    }

    public void WriteXml(XmlWriter writer)
    {
        foreach (var serialNumber in this)
        {
            writer.WriteElementString("Type", serialNumber.Type);
            writer.WriteElementString("Number", serialNumber.Number);
        }
    }
}

public class SerialNumber
{
    public string Type { get; set; }
    public string Number { get; set; }
}

示例:

var ser = new XmlSerializer(typeof(SerialNumbers));

var reader = new StringReader(@"
    <SerialNumbers>
        <Type>SN</Type>
        <Number>CBS583ABC123</Number>
        <Type>IMEI</Type>
        <Number>35-924106-659945-4</Number>
    </SerialNumbers>
".Trim());
var result = (SerialNumbers) ser.Deserialize(reader);

var writer = new StringWriter();
ser.Serialize(writer, result);

结果:

<?xml version="1.0" encoding="utf-16"?>
<SerialNumbers>
  <Type>SN</Type>
  <Number>CBS583ABC123</Number>
  <Type>IMEI</Type>
  <Number>35-924106-659945-4</Number>
</SerialNumbers>

答案 1 :(得分:0)

这可能会为你做到这一点

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class SerialNumbers
{
    private string[] itemsField;
    private ItemsChoiceType[] itemsElementNameField;
    [System.Xml.Serialization.XmlElementAttribute("Number", typeof(string))]
    [System.Xml.Serialization.XmlElementAttribute("Type", typeof(string))]
    [System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")]
    public string[] Items
    {
        get
        {
            return this.itemsField;
        }
        set
        {
            this.itemsField = value;
        }
    }

    [System.Xml.Serialization.XmlElementAttribute("ItemsElementName")]
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public ItemsChoiceType[] ItemsElementName
    {
        get
        {
            return this.itemsElementNameField;
        }
        set
        {
            this.itemsElementNameField = value;
        }
    }
}

[System.Xml.Serialization.XmlTypeAttribute(IncludeInSchema = false)]
public enum ItemsChoiceType
{
    Number,
    Type,
}