将XML反序列化为对象数组

时间:2015-03-24 14:29:13

标签: c# xml serialization

这是一个相对常见的问题(从问题的数量来看),但我遇到的问题似乎有所不同(其他解决方案似乎都不适用)。

我试图将XML序列化添加到已经被序列化的类中,并通过线路"。我的班级结构是这样的:

[StructLayout(LayoutKind.Sequential)]
public struct G
{
    public PN P;
    public byte FillerByte;
    public PRD PDef;
}
[StructLayout(LayoutKind.Sequential)]
public struct PRD
{
    [MarshalAs(UnmanagedType.U1)]
    public bool PD1;
    [MarshalAs(UnmanagedType.U1)]
    public bool PD2;
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = CPD.NameChars)]
    public String PN;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = CPF.Bytes)]
    public byte[] AF;
    public byte PFI;
    public PSB PV;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = NumPLD)]
    public PLD[] PLD;
    // NumPLD = 4
    // Yes, both the class and this member variable are named PLD
}

当我序列化它时,XML看起来很好:

<?xml version="1.0" encoding="utf-16"?>
<G xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<P>_2</P>
<FillerByte>0</FillerByte>
<PDef>
   <PD1>false</PD1>
   <PD2>false</PD2>
   <PN>P A</PN>
   <PFI>0</PFI>
   <PV>None</PV>  
   <PLD>
      <PLD>
         <..contents of first PLD>
      </PLD>
      <PLD>
         <..contents of second PLD>
      </PLD>
      <PLD>
         <..contents of third PLD>
      </PLD>
      <PLD>
         <..contents of fourth PLD>
      </PLD>
   </PLD>
</PDef>
</G>

当我反序列化时,除PLD数组外,一切都很好。我有处理程序捕获所有各种错误:

System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(G));
x.UnknownAttribute += new System.Xml.Serialization.XmlAttributeEventHandler(UnknownAttribute);
x.UnknownElement += new System.Xml.Serialization.XmlElementEventHandler(UnknownElement);
x.UnknownNode += new System.Xml.Serialization.XmlNodeEventHandler(UnknownNode);
x.UnreferencedObject += new System.Xml.Serialization.UnreferencedObjectEventHandler(UnreferencedObject);

这些事件都没有被触发。

如何说服XML解析器反序列化我的PLD对象数组?我有问题,因为类名和成员变量名是相同的(&#34; PLD&#34;)?


我创建了一个更简单的示例来显示问题,它似乎与嵌套结构有关:

public struct Fred
{
    public string Name;
}

public struct Middle
{
    public Fred[] Freds;
}

public struct Top
{
    public Middle Middle;
    public Fred[] Freds;
}

public static void Test()
{
    Top top = new Top();
    top.Middle.Freds = new Fred[2];
    top.Middle.Freds[0].Name = "Fred20";
    top.Middle.Freds[1].Name = "Fred21";

    top.Freds = new Fred[2];
    top.Freds[0].Name = "Fred10";
    top.Freds[1].Name = "Fred11";

    StringBuilder sb = new StringBuilder();
    System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(top.GetType());
    using (StringWriter sw = new StringWriter(sb))
    {
        x.Serialize(sw, top);
    }
    string xml = sb.ToString();

    string[] lines = xml.Split(new char[] { '\r', '\n' });
    foreach (string line in lines)
    {
        Debug.WriteLine("   " + line.Trim());
    }

    MemoryStream ms = new MemoryStream(System.Text.Encoding.ASCII.GetBytes(xml));
    StreamReader sr = new StreamReader(ms);
    object o = x.Deserialize(sr);
    Debug.WriteLine("Deserialized into " + o);
     Top go2 = (Top)o;

    if (go2.Freds == null)
        Debug.WriteLine("   go2.Freds is null");
    else
        Debug.WriteLine("   go2.Freds[0].Name is \"" + go2.Freds[0].Name + "\"");
    if (go2.Middle.Freds == null)
        Debug.WriteLine("   go2.Middle.Freds is null");
    else
        Debug.WriteLine("   go2.Middle.Freds[0].Name is \"" + go2.Middle.Freds[0].Name + "\"");

}

XML看起来不错:

<?xml version="1.0" encoding="utf-16"?>
<Top xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Middle>
     <Freds>
        <Fred>
           <Name>Fred20</Name>
        </Fred>
        <Fred>
           <Name>Fred21</Name>
        </Fred>
     </Freds>
  </Middle>
  <Freds>
     <Fred>
        <Name>Fred10</Name>
     </Fred>
     <Fred>
        <Name>Fred11</Name>
     </Fred>
  </Freds>
</Top>

但是当我运行它时,我明白了:

Deserialized into Top
go2.Freds[0].Name is "Fred10"
go2.Middle.Freds is null

xsd也错了:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Top" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="Top" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
  <xs:choice minOccurs="0" maxOccurs="unbounded">
    <xs:element name="Middle">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="Freds" minOccurs="0" maxOccurs="unbounded">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="Fred" minOccurs="0" maxOccurs="unbounded">
                  <xs:complexType>
                    <xs:sequence>
                      <xs:element name="Name" type="xs:string" minOccurs="0" />
                    </xs:sequence>
                  </xs:complexType>
                </xs:element>
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
  </xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>

1 个答案:

答案 0 :(得分:0)

有时作为一种技巧,我将使用visual studio命令行工具&#39; xsd.exe&#39;对于像这样的事情。跑

xsd.exe result.xml 
在您的xml文件上

并获取xsd。然后在结果.xsd文件

上再次运行xsd
xsd.exe result.xsd /c 

并将您获得的课程与您所拥有的课程进行比较。这可能会回答你的问题

相关问题