【问题标题】:C# - XML serialization: omitting a certain element in my XML outputC# - XML 序列化:在我的 XML 输出中省略某个元素
【发布时间】:2016-12-02 08:12:04
【问题描述】:

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

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

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>        

所以基本上,列表元素需要被省略——我只需要一个容器&lt;SerialNumbers&gt;,然后对于列表中的每个条目,我只需要序列化出TypeNumber 子元素。

如何在 .NET 中使用 XmlSerializer 轻松做到这一点?

我尝试使用

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

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

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

是否有一个简单的技巧来实现我正在寻找的东西?我宁愿去低级并开始手动将我的 XML 合并在一起....

谢谢!

【问题讨论】:

标签: c# xml xml-serialization


【解决方案1】:

您可以通过 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>

【讨论】:

    【解决方案2】:

    这可能对你有用

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

    【讨论】:

    • 抱歉,这根本不起作用 - 我在尝试序列化时不断收到“反射错误”......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多