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

C# - XML serialization: omitting a certain element in my XML output

我这里有一个奇怪的 XML 设置:我需要与第三方交互,他们使用的 XML 布局超出了我的控制范围 - 没有机会更改任何内容。 ..

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

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

这会通常List<SerialNumber> SerialNumbers序列化为

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

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

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

所以基本上,列表元素需要省略 - 我只需要一个容器 <SerialNumbers> 然后对于列表中的每个条目,我只需要序列化 ​​TypeNumber 子元素。

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

我尝试使用

[XmlRoot(ElementName="")]
public class SerialNumber

[XmlArray]
[XmlArrayItem(ElementName = "")]
public List<SerialNumber> SerialNumbers { get; set; }

但这些都不起作用 - 我仍然使用 <SerialNumbers> 容器内的 <SerialNumber> 元素获得 完整 序列化...

有什么简单的技巧可以实现我想要的吗?我宁愿 而不是 进入低级并开始手动合并我的 XML ....

谢谢!

这可能对你有用

[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,
}

您可以将自定义序列化与 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>