【问题标题】:C# xml serialization remove jagged array element nameC# xml 序列化删除锯齿状数组元素名称
【发布时间】:2012-02-04 06:01:23
【问题描述】:

我有以下课程:

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>

我正在尝试摆脱 Batch 元素。我希望 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[]'

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

【问题讨论】:

  • 我刚刚编辑了我的答案,试试看。我认为它应该有效。

标签: c# xml serialization


【解决方案1】:

您尝试完成的任务似乎不受本机支持;无法将XmlElement 属性应用于锯齿状数组。见XmlSerializer bug when serializing collection of collections without root element?

但是,您可以将Field[][] 锯齿状数组分解为一个新类型的简单数组——我们将其命名为Batch——它又包含一个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:

<?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"},
                    }
                }
            }
        }
    };

...会生成:

<?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="2">5</RequestSize>
    <BatchEntry>
      <ParameterEntry name="AAA">111</ParameterEntry>
      <ParameterEntry name="BBB">222</ParameterEntry>
      <ParameterEntry name="CCC">333</ParameterEntry>
    </BatchEntry>
    <BatchEntry>
      <ParameterEntry name="DDD">444</ParameterEntry>
      <ParameterEntry name="EEE">555</ParameterEntry>
    </BatchEntry>
  </Parameters>
</MainRequest>

【讨论】:

    【解决方案2】:

    通过实验,您必须将Batch 重命名为BatchEntry(显然您不能将XmlElement 和XmlArrayItem 组合在一起),然后您可以使用名称为“ParameterEntry”的XmlArrayItem 属性。

    这将起作用:

    /* No idea why this a 2-d array... It doesn't match your XML */
    [XmlArrayItem("ParameterEntry")]
    public Field[] BatchEntry    //was Batch
    

    【讨论】:

      【解决方案3】:

      试试类似的东西

          [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(); 
              }
          }
      

      【讨论】:

        猜你喜欢
        • 2021-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-20
        • 2023-03-04
        • 2010-12-16
        • 2019-04-21
        • 1970-01-01
        相关资源
        最近更新 更多