C#xml序列化删除锯齿状数组元素名称

时间:2012-02-03 21:03:41

标签: c# xml serialization

我有以下课程:

public class MainRequest
{
    private Request _dataField;

    [XmlElementAttribute("Parameters")]
    public Request Parameters
    {
        get
        {
            return _dataField;
        }
        set
        {
            _dataField = value;
        }
    }
}


public class Request
{
    private RequestSize _requestSize;

    private Field[][] _field;

    [XmlElementAttribute(IsNullable = true)]
    public RequestSize RequestSize
    {
        get
        {
            return _requestSize;
        }
        set
        {
            _requestSize = value;
        }
    }

    [XmlArrayItem("BatchEntry")]
    [XmlArrayItemAttribute("ParameterEntry", IsNullable = false, NestingLevel = 1)]
    public Field[][] Batch
    {
        get
        {
            return _field;
        }
        set
        {
            _field = value;
        }
    }
}

public class RequestSize
{
    private string _count;

    private string _value;

    [XmlAttributeAttribute]
    public string Count
    {
        get
        {
            return _count;
        }
        set
        {
            _count = value;
        }
    }

    [XmlTextAttribute]
    public string Value
    {
        get
        {
            return _value;
        }
        set
        {
            _value = value;
        }
    }
}


public class Field
{

    private string _fieldName;

    private string _fieldValue;

    [XmlAttributeAttribute(AttributeName = "name")]
    public string Name
    {
        get
        {
            return _fieldName;
        }
        set
        {
            _fieldName = value;
        }
    }

    [XmlTextAttribute]
    public string Value
    {
        get
        {
            return _fieldValue;
        }
        set
        {
            _fieldValue = value;
        }
    }
}

当它们被序列化时,我得到:

<Parameters>
  <RequestSize Count="1">2</RequestSize>
  <Batch>
    <BatchEntry>
      <ParameterEntry name="AAA">111</ParameterEntry>
      <ParameterEntry name="BBB">222</ParameterEntry>
      <ParameterEntry name="CCC">333</ParameterEntry>
    </BatchEntry>
  </Batch>
</Parameters>

我正在尝试摆脱批次元素。我希望xml看起来像是:

<Parameters>
  <RequestSize Count="1">2</RequestSize>
  <BatchEntry>
    <ParameterEntry name="AAA">111</ParameterEntry>
    <ParameterEntry name="BBB">222</ParameterEntry>
    <ParameterEntry name="CCC">333</ParameterEntry>
  </BatchEntry>
</Parameters>

我尝试在Field [] []上使用XmlElement属性但是当我这样做时出现错误:

[XmlElement("Batch")]
public Field[][] Batch
{
    get
    {
        return _field;
    }
    set
    {
        _field = value;
    }
}



Error   97  Cannot convert type 'Field[][]' to 'Field[]'

有没有一种方法可以序列化没有顶级元素名称的数组元素?

3 个答案:

答案 0 :(得分:3)

看起来你想要完成的东西本身不受支持;没有办法将XmlElement属性应用于锯齿状数组。见XmlSerializer bug when serializing collection of collections without root element?

但是,您可以做的是将Field[][]锯齿状数组分解为一个新类型的简单数组 - 让我们将其命名为Batch - 这将包含{{1}的数组}类型。以下代码生成您正在使用的XML:

Field

生成的XML:

public class MainRequest
{
    [XmlElementAttribute("Parameters")]
    public Request Parameters { get; set; }
}

public class Request
{
    [XmlElementAttribute(IsNullable = true)]
    public RequestSize RequestSize { get; set; }

    [XmlElement("BatchEntry")]
    public Batch[] Batches { get; set; }
}

public class RequestSize
{
    [XmlAttributeAttribute]
    public string Count { get; set; }

    [XmlTextAttribute]
    public string Value { get; set; }
}

public class Batch
{
    [XmlElementAttribute("ParameterEntry")]
    public Field[] Fields { get; set; }
}

public class Field
{
    [XmlAttributeAttribute(AttributeName = "name")]
    public string Name { get; set; }

    [XmlTextAttribute]
    public string Value { get; set; }
}

public static void Main(string[] args)
{
    var request = new MainRequest
    {
        Parameters = new Request
        {
            RequestSize = new RequestSize
            {
                Count = "1",
                Value = "2",
            },
            Batches = new Batch[]
            {
                new Batch 
                { 
                    Fields = new Field[] 
                    { 
                        new Field { Name = "AAA", Value = "111"},
                        new Field { Name = "BBB", Value = "222"},
                        new Field { Name = "CCC", Value = "333"},
                    }
                }
            }
        }
    };

    using (var stream = new MemoryStream())
    using (var reader = new StreamReader(stream))
    {
        XmlSerializer serializer = new XmlSerializer(typeof(MainRequest));
        serializer.Serialize(stream, request);

        stream.Seek(0, SeekOrigin.Begin);
        var str = reader.ReadToEnd();
    }
}

这种方法的优点是,如果您定义多个批次,它仍然可以工作。例如:

<?xml version="1.0"?>
<MainRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Parameters>
    <RequestSize Count="1">2</RequestSize>
    <BatchEntry>
      <ParameterEntry name="AAA">111</ParameterEntry>
      <ParameterEntry name="BBB">222</ParameterEntry>
      <ParameterEntry name="CCC">333</ParameterEntry>
    </BatchEntry>
  </Parameters>
</MainRequest>

......会产生:

    var request = new MainRequest
    {
        Parameters = new Request
        {
            RequestSize = new RequestSize
            {
                Count = "2",
                Value = "5",
            },
            Batches = new Batch[]
            {
                new Batch 
                { 
                    Fields = new Field[] 
                    { 
                        new Field { Name = "AAA", Value = "111"},
                        new Field { Name = "BBB", Value = "222"},
                        new Field { Name = "CCC", Value = "333"},
                    }
                },
                new Batch 
                { 
                    Fields = new Field[] 
                    { 
                        new Field { Name = "DDD", Value = "444"},
                        new Field { Name = "EEE", Value = "555"},
                    }
                }
            }
        }
    };

答案 1 :(得分:0)

通过实验,您必须将Batch重命名为BatchEntry(显然您无法合并XmlElementXmlArrayItem)然后您可以{{1}名称为“ParameterEntry”的属性。

这将有效:

XmlArrayItem

答案 2 :(得分:0)

尝试类似

的内容
    [XmlIgnore]
    public Field[][] Batch
    {
        get
        {
            return _field;
        }
        set
        {
            _field = value;
        }
    }
    [XmlArrayItemAttribute("ParameterEntry", IsNullable = false)]
    public Field[] BatchEntry
    {
        get
        {
            List<Field> OneDimFields = new List<Field>();
            foreach(Field[] field in _field)
            {
                OneDimFields.AddRange(field);
            }
            return OneDimFields.ToArray(); 
        }
    }