【问题标题】:Trying to deserialize XML to C# object试图将 XML 反序列化为 C# 对象
【发布时间】:2011-03-26 14:45:56
【问题描述】:

我有一个 XML 文件,它表示 UI 中的表单的序列化实例。此表单由用户设计,并允许其他用户填写表单。保存表单后,实例数据将序列化到数据库中的列。我正在调用这个实例数据,我需要解析它,但在反序列化中遇到了问题 - 使用 C# 标准反序列化。就用户而言,这是一个表单,但实例数据实际上是由“子表单”组成的——这些是用户看到的表单所包含的表单。

这是 XML 文档的格式:

 <Thing>
  <TheSections>
    <TheSection>
      <TheForms>
        <TheForm name="SomeUserForm">
          <Property name="BackgroundColor"/>
          <Control name="GroupHeading1" type="header" hasdata="N">
            <Control name="GroupHeading2" type="subheader" hasdata="N">
              <Control name="TextEntry1" type="detail" hasdata="Y">
                <Property name="ValueField">I want to order 3 of these</Property>
                <Property name="Type">TextField</Property>
              </Control>
            </Control>
          </Control>
        </Form>
        <Form>....</Form>
        <Form>....</Form>
        <Form>....</Form>
      </TheForms>
    </TheSection>
    <TheSection>...</TheSection>
  </TheSections>
</Thing>

如您所见,控件可以嵌套在其他控件中,属性是控件的一部分。

我将反序列化工作到表单级别,但是当我尝试反序列化控件时它会中断。

此文件中的嵌套控件对我来说并不重要 - 因为我希望获得所有控件的一个级别集合,无论层次结构及其所有属性如何。我想向 Controls 添加一个属性,该属性指示它们的 Control 父名称(如果有的话) - 但除此之外,我想要一个具有 Controls 及其属性的平面集合的对象。

有没有办法让反序列化查看这个 XML,就好像所有控件都在同一级别,而不管它们的层次结构如何,并且只是自动反序列化所有嵌套?

感谢您的任何提示!

这是从 Visual Studio 2008 中的 XML 文件生成的 XSD(如您所见,原始 XML 在每个表单上方没有表单或在每个部分上方没有部分 - 我在加载 XML 时添加了它:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Thing">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="TheSection">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="TheForm">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element maxOccurs="unbounded" name="Control">
                      <xs:complexType mixed="true">
                        <xs:sequence>
                          <xs:element name="Group">
                            <xs:complexType>
                              <xs:sequence minOccurs="0">
                                <xs:element maxOccurs="unbounded" name="GroupItem">
                                  <xs:complexType>
                                    <xs:attribute name="name" type="xs:string" use="required" />
                                    <xs:attribute name="taborder" type="xs:unsignedByte" use="required" />
                                    <xs:attribute name="posneg" type="xs:string" use="required" />
                                    <xs:attribute name="qualifier" type="xs:string" use="required" />
                                  </xs:complexType>
                                </xs:element>
                              </xs:sequence>
                              <xs:attribute name="name" type="xs:string" use="required" />
                              <xs:attribute name="render" type="xs:string" use="required" />
                              <xs:attribute name="size" type="xs:unsignedByte" use="required" />
                              <xs:attribute name="indent" type="xs:string" use="required" />
                              <xs:attribute name="newline" type="xs:string" use="required" />
                            </xs:complexType>
                          </xs:element>
                          <xs:element minOccurs="0" maxOccurs="unbounded" name="Control">
                            <xs:complexType mixed="true">
                              <xs:sequence minOccurs="0">
                                <xs:element maxOccurs="unbounded" name="Property">
                                  <xs:complexType>
                                    <xs:simpleContent>
                                      <xs:extension base="xs:string">
                                        <xs:attribute name="name" type="xs:string" use="required" />
                                      </xs:extension>
                                    </xs:simpleContent>
                                  </xs:complexType>
                                </xs:element>
                              </xs:sequence>
                              <xs:attribute name="name" type="xs:string" use="required" />
                              <xs:attribute name="hasdata" type="xs:string" use="required" />
                              <xs:attribute name="type" type="xs:string" use="required" />
                              <xs:attribute name="font" type="xs:string" use="required" />
                              <xs:attribute name="size" type="xs:unsignedByte" use="required" />
                              <xs:attribute name="indent" type="xs:string" use="required" />
                              <xs:attribute name="bold" type="xs:string" use="required" />
                              <xs:attribute name="bullet" type="xs:string" use="required" />
                              <xs:attribute name="newline" type="xs:string" use="required" />
                              <xs:attribute name="render" type="xs:string" use="required" />
                              <xs:attribute name="forceparagraph" type="xs:string" use="required" />
                              <xs:attribute name="startnewsentence" type="xs:string" use="required" />
                              <xs:attribute name="commadelimited" type="xs:string" use="required" />
                              <xs:attribute name="qualifier" type="xs:string" use="required" />
                            </xs:complexType>
                          </xs:element>
                          <xs:element minOccurs="0" name="RenderText" type="xs:string" />
                        </xs:sequence>
                        <xs:attribute name="name" type="xs:string" use="required" />
                        <xs:attribute name="hasdata" type="xs:string" use="required" />
                        <xs:attribute name="type" type="xs:string" use="required" />
                        <xs:attribute name="font" type="xs:string" use="required" />
                        <xs:attribute name="size" type="xs:unsignedByte" use="required" />
                        <xs:attribute name="indent" type="xs:string" use="required" />
                        <xs:attribute name="bold" type="xs:string" use="required" />
                        <xs:attribute name="bullet" type="xs:string" use="required" />
                        <xs:attribute name="newline" type="xs:string" use="required" />
                        <xs:attribute name="render" type="xs:string" use="required" />
                        <xs:attribute name="forceparagraph" type="xs:string" use="required" />
                        <xs:attribute name="startnewsentence" type="xs:string" use="required" />
                        <xs:attribute name="commadelimited" type="xs:string" use="required" />
                        <xs:attribute name="qualifier" type="xs:string" use="required" />
                        <xs:attribute name="headinglevel" type="xs:unsignedByte" use="required" />
                        <xs:attribute name="normalgroup" type="xs:string" use="required" />
                        <xs:attribute name="renderwithdata" type="xs:string" use="required" />
                        <xs:attribute name="grouptype" type="xs:string" use="required" />
                        <xs:attribute name="label" type="xs:string" use="required" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                  <xs:attribute name="id" type="xs:string" use="required" />
                  <xs:attribute name="name" type="xs:string" use="required" />
                  <xs:attribute name="type" type="xs:string" use="required" />
                  <xs:attribute name="font" type="xs:string" use="required" />
                  <xs:attribute name="size" type="xs:unsignedByte" use="required" />
                  <xs:attribute name="indent" type="xs:string" use="required" />
                  <xs:attribute name="bold" type="xs:string" use="required" />
                  <xs:attribute name="bullet" type="xs:string" use="required" />
                  <xs:attribute name="newline" type="xs:string" use="required" />
                  <xs:attribute name="forceparagraph" type="xs:string" use="required" />
                  <xs:attribute name="startnewsentence" type="xs:string" use="required" />
                  <xs:attribute name="commadelimited" type="xs:string" use="required" />
                  <xs:attribute name="qualifier" type="xs:string" use="required" />
                  <xs:attribute name="render" type="xs:string" use="required" />
                  <xs:attribute name="rendercount" type="xs:unsignedByte" use="required" />
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute name="type" type="xs:string" use="required" />
            <xs:attribute name="id" type="xs:unsignedByte" use="required" />
            <xs:attribute name="name" type="xs:string" use="required" />
            <xs:attribute name="render" type="xs:string" use="required" />
            <xs:attribute name="font" type="xs:string" use="required" />
            <xs:attribute name="size" type="xs:unsignedByte" use="required" />
            <xs:attribute name="indent" type="xs:string" use="required" />
            <xs:attribute name="bold" type="xs:string" use="required" />
            <xs:attribute name="bullet" type="xs:string" use="required" />
            <xs:attribute name="newline" type="xs:string" use="required" />
            <xs:attribute name="forceparagraph" type="xs:string" use="required" />
            <xs:attribute name="rendercount" type="xs:unsignedByte" use="required" />
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

这是我用于反序列化的类的示例:

[ XmlRoot("Section")
    ]
    public class MySectionData
    {
        private MyFormData[] _Forms = new MyFormData[0];

        [ XmlArray("Forms")
        ]
        [ XmlArrayItem("Form")
        ]
        public MyFormData[] Forms
        {
            set
            {
                this._Forms = value;
            }
            get
            {
                return this._Forms;
            }
        }

        [ XmlAttribute("id")
        ]
        public String Id
        {
            set;
            get;
        }
        [XmlAttribute("name")
     ]
        public String name
        {
            set;
            get;
        }

    }

【问题讨论】:

  • 您可以发布您用于反序列化的架构或类吗?
  • 既然你有一个xsd,你可以看看linqtoXsd。 linqtoxsd.codeplex.com
  • 哇,那个模式就像 ASCII 艺术。是的,我认为你将不得不手动反序列化它以获得你想要的东西。
  • 尝试使用 xsd.exe /classes myschema.xsd 生成类
  • 我尝试生成这样的类,并且还使用 XSD2Code,但是关于嵌套或集合的某些内容使其无法真正工作。

标签: c# xml deserialization


【解决方案1】:

您可能会花费大量时间和精力来弄清楚 XML 序列化的细微差别并尝试构建类,以便它们或多或少地使用这种格式。不过,我认为这更容易:

  1. 创建一个可序列化为 XML 的 Control 类。创建一个包含Control 对象集合的可序列化类,填充它并对其进行序列化。现在您知道 XML 反序列化器希望此类输入的类型。

  2. 编写一个 XSLT 转换,将您拥有的输入 XML 转换为您需要的输入 XML。

【讨论】:

    【解决方案2】:

    您是否尝试过使用 xsd.exe 根据您的架构生成类?如果“控件”最终被嵌套,您仍然可以编写一个函数来“展平”它们并返回整个集合,对吗?

    它位于:C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\

    【讨论】:

      猜你喜欢
      • 2014-11-30
      • 1970-01-01
      • 2018-07-17
      • 2023-03-29
      • 1970-01-01
      • 2018-10-11
      • 2010-09-18
      • 1970-01-01
      相关资源
      最近更新 更多