【问题标题】:c# xml serializable multiple arrayitems时间:2019-01-01 标签:c#xmlserializablemultiplearrayitems
【发布时间】:2012-09-24 15:51:07
【问题描述】:

我在尝试让我的程序反序列化多个 XmlArrayItem 时遇到了一个相当愚蠢的问题。

XML 基本上是这样的:

<Root2>
   <Data2>
     <HOLD>
      ...
     </HOLD>
     <CUST_HOLD>
      ...
     </CUST_HOLD>
   </DATA2>
</ROOT2>

我的可序列化代码如下:

[Serializable()]
[System.Xml.Serialization.XmlRoot("Root2")]
public class Root2
{
    [System.Xml.Serialization.XmlArray("Data2")]           
    [System.Xml.Serialization.XmlArrayItem("CUST_HOLD", typeof(CUST_HOLD))]
    public CUST_HOLD[] CUST_HOLD { get; set; }
    [System.Xml.Serialization.XmlArrayItem("HOLD", typeof(HOLD))]
    public HOLD[] HOLD { get; set; }    

}

我尝试了不同的配置,但这是唯一不会导致错误的配置。 但问题是,只有第一个 XmlArrayItem 得到处理(在本例中为 CUST_HOLD)。 另一个保持为空,而相应的数组中应该至少有一个项目。

【问题讨论】:

  • 你试过 XmlElement 吗?
  • @CuongLe 你说得对,现在就处理它。
  • @MUG4N 我把XmlArrayItem 换成了XmlElement,如果这就是你的意思。不幸的是,这给出了 InvalidOperationException;反映类型“Root2”时出现错误。 :(
  • 让我直截了当地说...Data2 是数组外部节点,它包含Hold 和Cust_hold 条目?这似乎相当...效率低下。如果没有办法改善这一点,手动反序列化 xml 可能比尝试让序列化程序处理它更容易。使用一些 XSL 选择从 Data2 级别获取每个节点并编写解析器。
  • @Nevyn 事实上,我只是进行了更改以改进这种效率低下的结构。现在,我为 Cust_hold 条目获得了一个单独的数组外部节点,名为 Data3。而 Hold 条目仍保留在 Data2 中。到目前为止它似乎有效..

标签: c# xml serialization deserialization


【解决方案1】:

如果你不能为它写一个 xsd,你就不能将它序列化/反序列化为 xml。

这将是 xsd 中任何序列的序列或极差的集合。

【讨论】:

    【解决方案2】:

    试试看,

    代码

    类声明

    [Serializable()]
    [System.Xml.Serialization.XmlInclude(typeof(CUST_HOLD))]
    [System.Xml.Serialization.XmlInclude(typeof(HOLD))]
    [System.Xml.Serialization.XmlType(TypeName = "Data2")]
    public class Root2
    {
    
        [System.Xml.Serialization.XmlArrayItem("CUST_HOLD")]
        public CUST_HOLD[] CUST_HOLD;
    
    
         [System.Xml.Serialization.XmlArrayItem("HOLD")]
        public HOLD[] HOLD;
    
    }
    
     [Serializable()]
    [System.Xml.Serialization.XmlType("CUST_HOLD")]
    public class CUST_HOLD
    {
    
        public int i;
    }
    
    [Serializable()]
    [System.Xml.Serialization.XmlType("HOLD")]
    public class HOLD
    {
    
        public int i;
    }
    

    序列化

    List<Root2> list = new List<Root2>();
    Root2 obj = new Root2();
    obj.CUST_HOLD = new CUST_HOLD[] { new CUST_HOLD() { i = 1 }, new CUST_HOLD() { i = 1 }, new CUST_HOLD() { i = 1 } };
    obj.HOLD = new HOLD[] { new HOLD() { i = 1 }, new HOLD() { i = 1 }, new HOLD() { i = 1 } };
    
      list.Add(obj);
    
     //Serialize List<Root2>
     System.Xml.Serialization.XmlSerializer Serializer = new     System.Xml.Serialization.XmlSerializer(typeof(List<Root2>),new System.Xml.Serialization.XmlRootAttribute("Root2"));
    
     System.IO.MemoryStream mo = new System.IO.MemoryStream();
     Serializer.Serialize(mo, list);
     string str = UnicodeEncoding.UTF8.GetString(mo.ToArray());
    

    输出:

    <?xml version="1.0"?>
    <Root2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Data2>
    <CUST_HOLD>
      <CUST_HOLD>
        <i>1</i>
      </CUST_HOLD>
      <CUST_HOLD>
        <i>1</i>
      </CUST_HOLD>
      <CUST_HOLD>
        <i>1</i>
      </CUST_HOLD>
    </CUST_HOLD>
    <HOLD>
      <HOLD>
        <i>1</i>
      </HOLD>
      <HOLD>
        <i>1</i>
      </HOLD>
      <HOLD>
        <i>1</i>
      </HOLD>
    </HOLD>
    </Data2>
    </Root2>
    

    反序列化

    string str = @"<?xml version='1.0'?>
    <Root2 xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'  xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
    <Data2>
    <CUST_HOLD>
      <CUST_HOLD>
        <i>1</i>
      </CUST_HOLD>
      <CUST_HOLD>
        <i>1</i>
      </CUST_HOLD>
      <CUST_HOLD>
        <i>1</i>
      </CUST_HOLD>
    </CUST_HOLD>
    <HOLD>
      <HOLD>
        <i>1</i>
      </HOLD>
      <HOLD>
        <i>1</i>
      </HOLD>
      <HOLD>
        <i>1</i>
      </HOLD>
    </HOLD>
    </Data2>
    </Root2>";
    
    System.Xml.Serialization.XmlSerializer Serializer = new System.Xml.Serialization.XmlSerializer(typeof(List<Root2>), new System.Xml.Serialization.XmlRootAttribute("Root2"));
    
    System.IO.MemoryStream mo = new   System.IO.MemoryStream(UnicodeEncoding.UTF8.GetBytes(str));
    
    List<Root2> list = (List<Root2>)Serializer .Deserialize(mo);
    

    注意 &lt;Data2&gt; 标签仅在序列化类型为 List&lt;Root2&gt; 时出现,对于单个 Root2 实例 &lt;Data2&gt; 标签不会显示在 xml 字符串中,并且无法进行反序列化。反序列化将为CUST_HOLDHOLD 返回空值。返回类型应为List&lt;Root2&gt;

    【讨论】:

      猜你喜欢
      • 2018-01-03
      • 1970-01-01
      • 1970-01-01
      • 2014-11-14
      • 2019-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多